News for hackers. Stuff that matters.
Re:Rust: Dropping heavy things in another thread can make yo... by indemnity on Saturday May 30, 2020 @03:45PM (#23363986)
Isn’t a Rust “move” implemented as a bit wise copy (e.g. memcpy call)? I see people claiming move has no cost but I’m not sure that is true.
Re:Rust: Dropping heavy things in another thread can make yo... by justinpombrio on Saturday May 30, 2020 @03:52PM (#23364061)
EDIT: See kevincox's reply. Rust will bitwise copy the containing type, which is typically very cheap. For example, it you move a String, it will copy the String struct, which contains a couple pointers and a length (or something along those lines). Importantly, it will not copy the underlying char array.

I was thinking of the following code, where I believe the assignment to y is actually free. Though apparently this isn't called a "move".

    let x = <<large owned type like [char; 1000]>>;
    let y = x;
More info: https://doc.rust-lang.org/rust-by-example/scope/move.html
Re:Rust: Dropping heavy things in another thread can make yo... by kevincox on Saturday May 30, 2020 @04:19PM (#23364304)
Semantically it is a bitwise copy.

In the example from the article it is probably actually a copy because the value was originally on the parent thread's stack, which will be reused after the function returns, so the value will need to be copied to the new thread's stack.

However it is important to not that it isn't a deep/recursive bitwise copy. It just needs to copy the HashMap itself (which is probably a handful of words).

So yes, it is doing a bitwise copy, but this is also very cheap. It will be much, much cheaper than spawning the thread.

Re:Rust: Dropping heavy things in another thread can make yo... by ahupp on Saturday May 30, 2020 @04:52PM (#23364609)
That's not exactly true. In C++ terms, the example code is moving a value:

  std::map<...> foo;
  someFunction(std::move(foo));
And not moving a pointer like:

  std::unique_ptr<std::map<...>> foo = ...;
  someFunction(std::move(foo));
So it copies sizeof(std::map<...>), not a pointer.
Re:Rust: Dropping heavy things in another thread can make yo... by pjmlp on Monday June 01, 2020 @03:23AM (#23376073)
Not necessary, std::map::map(&&) is free to move just the internal pointers and bookkeeping data, only dumb implementations would move the memory blocks where the map data is actually stored, as per ISO C++ requirements.
Re:Rust: Dropping heavy things in another thread can make yo... by ahupp on Monday June 01, 2020 @02:01PM (#23381603)
The comment originally said it was the cost of a pointer copy, and I was pointing out it's not a pointer. eg., sizeof(std::map<std::string,std::string>) is 48, which is the "pointers and bookeeping" you mention.
Re:Rust: Dropping heavy things in another thread can make yo... by pjmlp on Tuesday June 02, 2020 @12:52AM (#23387593)
Ah sorry for the misinterpretation. Should have payed more attention.
Re:Rust: Dropping heavy things in another thread can make yo... by dathinab on Saturday May 30, 2020 @04:14PM (#23364250)
What is bit-wise copied is the pointer to the memory.

I.e. a `HashMap` struct, or `Vec` struct don't directly contain the data.

For example the `Vec` is defined internally as something similar to:

`struct Vec<T> { data: *mut [T], capacity: usize, len: usize, marker: PhantomData<T> }`

(Slightly simplified, not actual Vec type).

So a move of a Vec copies at most 3 usize (24 bytes on 64bit systems), similar thinks apply for a HashMap.

Additionally the copy can often be elided through compiler optimizations.

As a interesting side note a new empty Vec/HashMap will not actually allocate any memory, only once elements get added it will start doing so. This is why it crates vec's of vecs of length 1. Or else it wouldn't need to do "number of element" free calls.

Re:Rust: Dropping heavy things in another thread can make yo... by tsimionescu on Sunday May 31, 2020 @06:45AM (#23368633)
So the Vec type is not storing data on the stack, like C++'s std::vector can?
Re:Rust: Dropping heavy things in another thread can make yo... by cesarb on Sunday May 31, 2020 @07:42AM (#23368917)
Exactly, neither Rust's Vec nor Rust's String (which is actually a Vec in disguise) store data within the struct itself, it's always stored in an external allocation. This is intentional, to avoid extra branches on whether the data is inline or not. If you have a lot of small vectors, and using less memory is more important for your use case than avoiding the extra branches, there are alternatives like https://crates.io/crates/smallvec that you can use.
Re:Rust: Dropping heavy things in another thread can make yo... by steveklabnik on Saturday May 30, 2020 @04:03PM (#23364161)
Semantically, it is a bit wise copy, yes.

However, these copies can often be elided by optimizations.