3 ms·
Just glancing at that code: the use of unsafe is more or less only there to avoid initialization & bounds checking. Basically it's an optimization, and I don't
by drbawb 10y ago
Just glancing at that code: the use of unsafe is more or less only there to avoid initialization & bounds checking. Basically it's an optimization, and I don't think there's anything there that couldn't be accomplished in safe Rust.
I have an idea as to why the author approached it this way: typically Rust wouldn't let you take out a mutable borrow to a vector while you're iterating over it. If Rust did allow that and you modified the collection then the iterator might reference freed memory!
A common way around this is to just use a typical `for <range>` loop and index into the array directly to limit the scope of the mutable borrow to _a single iteration of the loop_ and not _the lifetime of the iterator._ However indexing in Rust incurs a speed penalty for bounds checking, and the unsafe code here lets you skip those checks.
Really all the unsafe code is doing is saying: "I promise to initialize `rowcol` entries, and I won't try to access anything outside `rowcol`. Please don't burn cycles worrying about it Friend Compiler."
It looks to me as though this could've been written as a vector initialized with all zeroes (which possibly isn't even that expensive, since modern OSes heavily optimize the case of giving you a zeroed page.) Then in the hot loop the author could've just used iterators to avoid the bounds check. Using an iterator for that should be fine in this instance since you're immutably iterating over one matrix, and the only mutation happening is in the new transposed matrix.
That all being said: transposing the matrix in-place would run into exactly that scenario. now you could still do it in safe rust, you would only need to add the unsafe code if you wanted to turn off the bounds checking for maximal performance.