You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here it introduces to boxes by showing us how we can move an array of 1 million integers from a variable a to a variable b. It suggests that doing that using boxes is more efficient than just doing a copy on the stack because moving a box doesn't actually do a copy.
The problem is this following line of code : let a = Box::new([0; 1_000_000]);. Looking at its assembly output, I discovered this actually sets 4 million bytes to zero on the stack before allocating 4MB on the heap and then actually performing a copy ! This happens only on debug mode. In release mode however, it doesn't happen only because the value we're assigning every integer of the array to is 0, but with anything else than 0, it does pretty much the same thing as in debug.
Since I'm never certain of what I understand from assembly, I verified this by replacing the value of 1 million by 10 millions, which as I expected, caused a stack overflow !
This means that the solution with Box is effectively worse than the one with just a raw copy on the stack. I find that to be pretty misleading since it's shown as being the solution to avoid copying, whereas, not only does it copies, but it copies from the stack to the heap (which is worse than a stack to stack copy). I think this should be done using vec! instead.
Edit: When I think about it I realise this moving over copying issue might just be a memory issue rather than a performance issue since allocating on the heap is probabely always slower anyway.
Still I think it is relevant to point at the fact that with Box::new, at some point, 4MB are pushed onto the stack, which could be avoided with the use of vec!
The text was updated successfully, but these errors were encountered:
To be clear, it only copies from the stack to the heap when constructing the box. Once the heap object is prepared, then pointers to it can be freely copied with no cost.
You're right that the stack-to-heap copy can be expensive. Rust does not have C++'s concept of "placement new", but not for lack of trying. See: rust-lang/rust#27779 (comment)
I will probably keep the book the same because the example still satisfies its intended purpose: showing the difference in behavior of copies between owned and boxed arrays.
https://rust-book.cs.brown.edu/ch04-01-what-is-ownership.html#boxes-live-in-the-heap
Here it introduces to boxes by showing us how we can move an array of 1 million integers from a variable a to a variable b. It suggests that doing that using boxes is more efficient than just doing a copy on the stack because moving a box doesn't actually do a copy.
The problem is this following line of code :
let a = Box::new([0; 1_000_000]);
. Looking at its assembly output, I discovered this actually sets 4 million bytes to zero on the stack before allocating 4MB on the heap and then actually performing a copy ! This happens only on debug mode. In release mode however, it doesn't happen only because the value we're assigning every integer of the array to is 0, but with anything else than 0, it does pretty much the same thing as in debug.Since I'm never certain of what I understand from assembly, I verified this by replacing the value of 1 million by 10 millions, which as I expected, caused a stack overflow !
This means that the solution with Box is effectively worse than the one with just a raw copy on the stack. I find that to be pretty misleading since it's shown as being the solution to avoid copying, whereas, not only does it copies, but it copies from the stack to the heap (which is worse than a stack to stack copy). I think this should be done using vec! instead.
Edit: When I think about it I realise this moving over copying issue might just be a memory issue rather than a performance issue since allocating on the heap is probabely always slower anyway.
Still I think it is relevant to point at the fact that with Box::new, at some point, 4MB are pushed onto the stack, which could be avoided with the use of vec!
The text was updated successfully, but these errors were encountered: