4 ms·
I wondered why rust is so far behind C/nim/zig, they should have similar behaviour. The difference is mostly in matmul. I see how C, for an n x n matrix, does
by hyperman1 3y ago
I wondered why rust is so far behind C/nim/zig, they should have similar behaviour.
The difference is mostly in matmul.
I see how C, for an n x n matrix, does 2 allocations, while rust does n+1. C's matrix rows are right next to each other, rusts are probably all over the place. Didn't look at nim or zig.
Maybe a slice of slice of double would perform better than a vec of vec of double? Then again, an argument can be made that rust pushes you to vec, so this impl is more honest for how a beginner would do it. Otoh, C has the optimization so why doesn't rust?
- nrabulinski 3y agoThe rust code is very unidiomatic, not only because of the Vec of Vecs which I’d say, even if it’s the obvious naive approach, no one experienced wouldn’t choose over a flat slice, the implementation itself is very naive and unidiomatic.
- hgomersall 3y agoAlso it's using checked indexing, which apart from being not idiomatic, is also going to slow things down. A fairer comparison would be to use the unchecked indexing variants.
- neonsunset 3y agoYeah, it's a similar problem in C# - ported code 1:1 is not representative since it now can't do out of bounds accesses and is therefore safe but comes at a cost of bounds checks which can be manually elided.
- vlovich123 3y agoUnchecked indexing is unidiomatic. A more fair comparison world be using iterators if possible but otherwise you have to live with that.
- tiehuis 3y agoZig had a similar issue which I made an MR to fix. I didn't actually notice Rust had the same issue but that's probably just my forgotten knowledge with how the vec! macros expand when nested.
- spense 3y agorust is equivalent to C when using static allocation i sent a pr to fix it
- Aissen 3y agoDoesn't your PR monomorphize the function every time N is changed ? I realize it's simpler since it keeps the structure, simplifies allocation of arrays, and elides bound check. But it explodes generated code size and matrix size can't be changed at runtime, which doesn't really match C. Edit: I have tried making an iterator-based version to elide bound checks, but had to resort to unsafe, and it's barely 50% faster than the original rust version (not as fast as C): https://gist.github.com/anisse/6b580628206293ef242faa7db6219bca https://gist.github.com/anisse/6b580628206293ef242faa7db6219... Edit 2: updated, and my rust iterator version now ~equivalent to C with no unsafe. Edit 3: too late, the repo has been updated with an other iterator-based version that is just as fast.
- spense 3y agoC, Nim and Zig all benefit from static allocation and it's available in rust, so seems fair? also, `const N` is used in rust's nqueen test, so figured it would be fine. someone posted an `.iter().zip()` solution which benchmarks only a little slower (+10ms) than static allocation: https://github.com/attractivechaos/plb2/pull/4#issuecomment-1875298577 https://github.com/attractivechaos/plb2/pull/4#issuecomment-...
- Aissen 3y agoI only looked at the C version, and it didn't use a generic over the allocation size, although yes, technically it was fixed at compile time. I saw the update to the PR, but I still prefer my collect()-based version :-)
- attractivechaos 3y agoFYI: rust has been updated to avoid unnecessary bound check in PR #4. It now matches the C version in performance.