Types with inner pointers add difficulty to be sure, but it’s still possible to use them with this pattern. You have to make sure of three things to do so: 1) no pointers outside of the backing memory; 2) an explicit “clear()” function that manually nulls out inner pointers in the stored object (even inner pointers to other things in the backing slice); 3) clear() is called for all such objects that were ever stored before the backing slice is dropped and before those objects are garbage collected.
> The page you linked compares golang bindings against each other, not C against golang like my test did
No one disputed that. But it follows that your benchmarks are comparing C to [some very] outdated versions of Go packages. Which is what I tried to point out.
That's an interesting result, thanks. I just calculated the geomean of all relations, which is 4.32. The original C code doesn't seem to make use of GCC-specific tricks such as computed gotos, so your experiment essentially demonstrates the optimization efficiency of the Go compiler compared to the C compiler. It would be interesting to use a more established benchmark suite like Are-we-fast-yet, which has a JS implementation.
Only if the type is not a pointer per se or does not contain any inner pointers.
Otherwise the garbage collector will bite you hard.