Commit b8d1c05
perf(vm): borrow callee name in vec dispatch instead of allocating 🪢 (#155)
## Summary
`dispatch_vec_call` and `dispatch_vec_call_dynamic` both eagerly built
an `Option<String>` for the callee's name on every call, then only read
it from rarely-taken error branches (the overload-not-found `Err` and
the `call_callback` `map_err` closure). The success path threw the
`String` away. Same shape of bug as the GetIterator fix in #147.
## Changes
- `dispatch_vec_call`: borrow `&str` directly from
`scalars.first().and_then(|f| f.name())`. The slice is a caller-owned
parameter, so the borrow lifetime is independent of `&mut self` and the
`map_err` closure can capture it freely.
- `dispatch_vec_call_dynamic`: resolve the first vec candidate once into
a held `Rc<Object>`, then borrow `&str` out of it. The `resolve_var`
call already happened inside the old `callee_name()`; the `.to_string()`
is what's gone.
- `Vm::callee_name()` itself is kept — it's still used from the regular
`Call` opcode's "no function found" error path, where the allocation is
fine because we're already on an error path.
## Caveat — perf impact is barely measurable
`vec_hot_loop` (200k–2M `(int,int) + (int,int)` calls):
| Iters | Baseline | This PR |
|---|---|---|
| 200k | 39.0 ± 3.4 ms | 38.6 ± 3.1 ms |
| 2M | 336.2 ± 3.8 ms | 334.5 ± 4.1 ms |
≈1.01× — within noise. `perf` confirms ~13% of total time goes to
malloc/free, but the eliminated allocation is one small `String`
(operator name like `"+"`) per outer vec call, dwarfed by
`Function::clone`, the per-call `Vec` allocations for
`arg_values`/`elem_args`/`results`, and the final
`Rc::new(Object::Tuple(...))`. Unlike the GetIterator case, there's no
deep recursive walk being saved here.
So this is more of a code-cleanliness/correctness fix (no wasted
allocation on the hot path; `&str` reads more naturally than
`Option<String>`) than a real perf win. Happy to drop it if you'd rather
not carry the churn.
🤖 PR description generated by Claude.
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>1 parent 7c2a345 commit b8d1c05
1 file changed
Lines changed: 24 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
893 | 893 | | |
894 | 894 | | |
895 | 895 | | |
896 | | - | |
897 | | - | |
898 | 896 | | |
899 | 897 | | |
900 | 898 | | |
901 | 899 | | |
902 | 900 | | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
903 | 917 | | |
904 | 918 | | |
905 | 919 | | |
| |||
935 | 949 | | |
936 | 950 | | |
937 | 951 | | |
938 | | - | |
| 952 | + | |
939 | 953 | | |
940 | 954 | | |
941 | 955 | | |
| |||
946 | 960 | | |
947 | 961 | | |
948 | 962 | | |
949 | | - | |
| 963 | + | |
950 | 964 | | |
951 | 965 | | |
952 | 966 | | |
| |||
973 | 987 | | |
974 | 988 | | |
975 | 989 | | |
976 | | - | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
977 | 994 | | |
978 | 995 | | |
979 | 996 | | |
| |||
1017 | 1034 | | |
1018 | 1035 | | |
1019 | 1036 | | |
1020 | | - | |
| 1037 | + | |
1021 | 1038 | | |
1022 | 1039 | | |
1023 | 1040 | | |
| |||
1028 | 1045 | | |
1029 | 1046 | | |
1030 | 1047 | | |
1031 | | - | |
| 1048 | + | |
1032 | 1049 | | |
1033 | 1050 | | |
1034 | 1051 | | |
| |||
0 commit comments