Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
btf: avoid heap allocations when walking types
Type.walk() forces the typeDeque argument to always escape, since the escape analyzer has to be conservative when dealing with interfaces. We can apply two tricks that reduce allocations. First, Type.walk() is replaced with children() []*Type This removes the typeDeque parameter, and for types that don't have any children (like Void) we never incur an allocation at all. For types that do have children we've unfortunately swapped heap allocating typeDeque with allocating the []*Type slice instead. Which brings us to the second trick: by using a type switch we allow the compiler to inline the children() function for the most important Types, which in turn enables allocating most []*Type on the stack instead of on the heap. One notable exception is FuncProto, which allocates the returned slice as such: types := make([]*Type, len(fp.Params)+1) It seems like this trips up escape analysis for some reason as the slice is heap allocated. name old time/op new time/op delta Walk/Void-4 22.6ns ± 2% 2.8ns ± 2% -87.40% (p=0.029 n=4+4) Walk/Int[unsigned_size=0]-4 22.7ns ± 1% 3.2ns ± 1% -86.09% (p=0.029 n=4+4) Walk/Pointer[target=<nil>]-4 61.3ns ± 1% 38.5ns ± 1% -37.26% (p=0.029 n=4+4) Walk/Array[index=<nil>_type=<nil>_n=0]-4 63.8ns ± 1% 42.2ns ± 0% -33.91% (p=0.029 n=4+4) Walk/Struct[fields=2]-4 64.9ns ± 1% 59.5ns ± 0% -8.29% (p=0.029 n=4+4) Walk/Union[fields=2]-4 66.6ns ± 3% 59.3ns ± 0% -10.84% (p=0.029 n=4+4) Walk/Enum[size=0_values=0]-4 22.5ns ± 4% 2.9ns ± 2% -87.22% (p=0.029 n=4+4) Walk/Fwd[struct]-4 22.2ns ± 1% 2.8ns ± 1% -87.23% (p=0.029 n=4+4) Walk/Typedef[<nil>]-4 60.8ns ± 1% 38.7ns ± 1% -36.42% (p=0.029 n=4+4) Walk/Volatile[<nil>]-4 62.9ns ± 3% 38.4ns ± 2% -38.89% (p=0.029 n=4+4) Walk/Const[<nil>]-4 61.9ns ± 1% 39.8ns ± 3% -35.78% (p=0.029 n=4+4) Walk/Restrict[<nil>]-4 64.2ns ± 1% 39.2ns ± 1% -38.91% (p=0.029 n=4+4) Walk/Func[static_proto=<nil>]-4 63.3ns ± 4% 39.5ns ± 2% -37.57% (p=0.029 n=4+4) Walk/FuncProto[args=2_return=<nil>]-4 67.8ns ± 5% 77.3ns ± 2% +14.03% (p=0.029 n=4+4) Walk/Var[static]-4 63.2ns ± 1% 38.5ns ± 0% -39.03% (p=0.029 n=4+4) Walk/Datasec-4 67.5ns ± 2% 58.5ns ± 1% -13.31% (p=0.029 n=4+4) name old alloc/op new alloc/op delta Walk/Void-4 48.0B ± 0% 0.0B -100.00% (p=0.029 n=4+4) Walk/Int[unsigned_size=0]-4 48.0B ± 0% 0.0B -100.00% (p=0.029 n=4+4) Walk/Pointer[target=<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Array[index=<nil>_type=<nil>_n=0]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Struct[fields=2]-4 112B ± 0% 80B ± 0% -28.57% (p=0.029 n=4+4) Walk/Union[fields=2]-4 112B ± 0% 80B ± 0% -28.57% (p=0.029 n=4+4) Walk/Enum[size=0_values=0]-4 48.0B ± 0% 0.0B -100.00% (p=0.029 n=4+4) Walk/Fwd[struct]-4 48.0B ± 0% 0.0B -100.00% (p=0.029 n=4+4) Walk/Typedef[<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Volatile[<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Const[<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Restrict[<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Func[static_proto=<nil>]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/FuncProto[args=2_return=<nil>]-4 112B ± 0% 88B ± 0% -21.43% (p=0.029 n=4+4) Walk/Var[static]-4 112B ± 0% 64B ± 0% -42.86% (p=0.029 n=4+4) Walk/Datasec-4 112B ± 0% 80B ± 0% -28.57% (p=0.029 n=4+4) name old allocs/op new allocs/op delta Walk/Void-4 1.00 ± 0% 0.00 -100.00% (p=0.029 n=4+4) Walk/Int[unsigned_size=0]-4 1.00 ± 0% 0.00 -100.00% (p=0.029 n=4+4) Walk/Pointer[target=<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Array[index=<nil>_type=<nil>_n=0]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Struct[fields=2]-4 2.00 ± 0% 2.00 ± 0% ~ (all equal) Walk/Union[fields=2]-4 2.00 ± 0% 2.00 ± 0% ~ (all equal) Walk/Enum[size=0_values=0]-4 1.00 ± 0% 0.00 -100.00% (p=0.029 n=4+4) Walk/Fwd[struct]-4 1.00 ± 0% 0.00 -100.00% (p=0.029 n=4+4) Walk/Typedef[<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Volatile[<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Const[<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Restrict[<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Func[static_proto=<nil>]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/FuncProto[args=2_return=<nil>]-4 2.00 ± 0% 2.00 ± 0% ~ (all equal) Walk/Var[static]-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.029 n=4+4) Walk/Datasec-4 2.00 ± 0% 2.00 ± 0% ~ (all equal)
- Loading branch information