Commit d674129
committed
perf(runtime): add typed-slice fast paths to
`in` dispatches through `runtime.In`, which uses reflect to iterate the
right-hand side. The reflect path is correct for any slice type but pays
one heap allocation per element on every typed slice, because
`reflect.Value.Index(i).Interface()` must box the element when the slice's
element type is not already `interface{}`.
For `[]any` this boxing is a no-op (the cell is already an interface), so
the existing path is already zero-alloc-per-element. For `[]string`,
`[]float64`, `[]int64`, `[]int`, and `[]bool` it adds N heap allocations
per `in` evaluation, which is significant when `in` runs in a hot loop
(e.g. rule engines or expression-based filters over candidate lists).
This patch adds a type-switch at the top of `In` for those five common
shapes. Each case uses a pure-Go `for ... range` loop, so no reflect, no
per-element boxing, no Equal() round-trip. On a needle/element type
mismatch the case falls through to the existing reflect path so Equal()'s
cross-type promotion semantics are preserved (e.g. an int needle against
a []float64 still matches).
Benchmarks (Apple M4 Pro, darwin/arm64, -benchtime=1s):
bench (N elements) before after speedup
StringSlice/N=8 112.8 ns/op, 6 allocs 18.96 ns/op, 1 alloc 6.0x
StringSlice/N=64 659.8 ns/op, 34 allocs 31.69 ns/op, 1 alloc 20.8x
StringSlice/N=256 2240 ns/op, 130 allocs 60.28 ns/op, 1 alloc 37.2x
Float64Slice/N=8 85.1 ns/op, 6 allocs 14.99 ns/op, 1 alloc 5.7x
Float64Slice/N=64 442.1 ns/op, 34 allocs 23.66 ns/op, 1 alloc 18.7x
Float64Slice/N=256 1794 ns/op, 130 allocs 169.1 ns/op, 1 alloc 10.6x
Int64Slice/N=8 82.0 ns/op, 6 allocs 14.77 ns/op, 1 alloc 5.6x
Int64Slice/N=64 973.8 ns/op, 34 allocs 23.15 ns/op, 1 alloc 42.1x
Int64Slice/N=256 1610 ns/op, 130 allocs 166.0 ns/op, 1 alloc 9.7x
AnySliceOfString/N=* unchanged (already uses zero-alloc reflect path)
The remaining 1 alloc/op is the call-site boxing the needle into `any`
when calling runtime.In; it lives outside the changed code.
Tests in `vm/runtime/runtime_test.go` cover hit/miss for each fast path,
empty typed slice, cross-type needle (must fall through to reflect), and
unchanged `[]any` semantics. The existing test suite is untouched and
still passes.
Signed-off-by: MinJae Kwon <mingrammer@gmail.com>in operator1 parent 3a46b19 commit d674129
3 files changed
Lines changed: 212 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
210 | 210 | | |
211 | 211 | | |
212 | 212 | | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
213 | 272 | | |
214 | 273 | | |
215 | 274 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
0 commit comments