3 ms·
Regarding binary trees: You can always go back to using old-fashioned arrays and indices. A few simple contiguous arrays of nodes (e.g. a key array and value ar
by electrograv 7y ago
Regarding binary trees: You can always go back to using old-fashioned arrays and indices. A few simple contiguous arrays of nodes (e.g. a key array and value array) is often all you need, where nodes simply refer to each other via int indices into these arrays. You may be surprised that this often yields some of the best-performing data structures, sometimes better than those using raw pointers and non-contiguous heap allocations.
And, this works in Rust just as it does in C. But at this point, you lose out on the benefits of Rust's static type system and borrow-checker:
1. The compiler will no longer be able to correctness-check the validity of these 'int' style references to other memory.
2. If something does go wrong and you read the array with a bad integer index, Rust will just 'panic' and crash the application. Unlike C, there will be no risk of memory errors or related security vulnerabilities. But on the other hand, each read being bounds-checked will make such Rust code slightly slower than is possible with C/C++. (Though I think you can use 'unsafe' blocks if you want to hyper-optimize akin to C.)
But regarding GC langauges, I generally agree; they're almost always more trouble than they're worth in any performance-sensitive context. You often end up using approaches like this to optimize around the GC (e.g. int indexes into pre-allocated arrays) which ultimately means you're coding C-style in a GC language anyway, which defeats the whole point of GC's productivity-enhancing benefit -- at that point, why not just go all the way and use C or Zig or Rust etc.?