These are chat archives for rust-lang/rust

8th
Dec 2016
Aleksey Kladov
@matklad
Dec 08 2016 09:27
@zenware in terms of performance, Arc requires you to heap allocate the data and incurs atomic write for each .clone. crossbeam is basically free, and you can share references to stack allocated data with zero runtime book keeping.
But for the task at hand performance is not important at all, because even cloning config will be dwarfed by the thread creating time.
But Arc and crossbeam have diffirent implications about your program structure. crossbeam enforces rigid tree structure for your program, and you always know precisely when resource will be freed. Arc allow to create a more flexible structure, which may be harder to understand.
Here's a great blog post (without mention of Rust :) ) which discusses the structure that crossbeam enforces: http://250bpm.com/blog:71
xialvjun
@xialvjun
Dec 08 2016 14:04
let v = vec![1, 2, 3];
let mut v2 = v;
v2.truncate(2);
println!(v[2]);    // imagine it compile, it will panic
In Rust doc, there is the case introduct the ownership, but I don't see the necessity.
Aleksey Kladov
@matklad
Dec 08 2016 14:06
Are you coming from C++ or from Java/Python/Ruby e.t.c?
In C++, let mut v2 = v would copy v and it indeed would be safe (but wasteful)
xialvjun
@xialvjun
Dec 08 2016 14:07
from js
Aleksey Kladov
@matklad
Dec 08 2016 14:08
Ah, so if v2 is an alias for v, then truncating v2 would truncate v as well, so v[2] would cause access out of bounds.
xialvjun
@xialvjun
Dec 08 2016 14:10
Yeah... panic is alright... The problem is it seems the book says: v is an object with ptr and length in the stack, let v2=v will copy v in the stack, but not the Vector in the heap. Then we change v2, but v has the old ptr and length...
Aleksey Kladov
@matklad
Dec 08 2016 14:11
Ah, they are implying even a more devilish problem!
v[2] would panic, if the length of v is less then 3.
However, if you change only the length of v2 and not the length of v while they are sharing the buffer, then v[2] won't generate a panic.
It would be an access to the destroyed object, which is undefined behavior.
xialvjun
@xialvjun
Dec 08 2016 14:13
yeah. So I think why we put the vector length in stack..
why not v and v2 just a ptr
then panic is alright, at least, we won't access an destroyed object
Aleksey Kladov
@matklad
Dec 08 2016 14:15
To have a vector, you need at least two pieces of data: the pointer to the memory with the elements, and the number of elements. You can't get the number of elements just from the pointer.
(In reality, there is a third piece of data: the amount of excessive capacity in the allocated buffer)
xialvjun
@xialvjun
Dec 08 2016 14:18
I think we can put the number of elements in the first byte where the pointer points in the heap.
Maybe not just a byte. but it's the same with vector length in the stack.
Aleksey Kladov
@matklad
Dec 08 2016 14:20
Yep, that layout can work I think.
xialvjun
@xialvjun
Dec 08 2016 14:23
So I need another example to tell why we introduce the concept ownership.
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:24
you could consider a Box instead of a Vec, there you don't have any extra data, it's literally just a pointer to some value on the heap
but yet you have the same problems a Vec have
if you have a variable holding a box, and you just copied that pointer to another variable, so that both of them point to the same area in the heap
better yet, send one of those to another thread which may live longer or shorter
how do you decide where in the code the heap should be deallocated?
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:29
basically, if you were to deallocate the Box in one place, while still having a pointer to that heap somewhere else, you run into undefined behavior (dangling pointer)
xialvjun
@xialvjun
Dec 08 2016 14:29
Oh, I see, in other language, we can not know when to destroy the object. But in Rust, although the compiler stricts us, but it also let we descroy the object safely even we needn't descroy manully..
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:29
yes, Rust effectively has "manual" memory management
just instead of having to worry about writing free, you just obey the ownership / borrowing rules and the compiler inserts those instructions for you
in JS the same problem is solved by the garbage collector, so you don't have to think about it
xialvjun
@xialvjun
Dec 08 2016 14:31
Thank you so much. I have stuck in this for days. And thanks @matklad too. :)
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:31
but GC has it's runtime cost, Rust's ownership model allows you to write code as performant as C or C++, with the safety guarantees of a GC but without the cost (the cost here is the borrow checker being annoying until you realize it's your friend ;))
as to why Vec is a trinity of pointer + len + capacity and doesn't store all of those on heap I don't really know, but I can guess
xialvjun
@xialvjun
Dec 08 2016 14:33
Yeah, if we don't know the theory, we may think the borrow checker as enemy. hahah
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:33
one is that a Vec of 0 elements doesn't actually allocate anything on the heap
if you put length and capacity on the heap, you'd always have to allocate, even for 0 elements
Aleksey Kladov
@matklad
Dec 08 2016 14:34

one is that a Vec of 0 elements doesn't actually allocate anything on the heap

You can do this even if you store length and capacity on

the heap
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:34
null pointer?
xialvjun
@xialvjun
Dec 08 2016 14:34
I think the example in the doc should change to this.
Aleksey Kladov
@matklad
Dec 08 2016 14:34
yep, null pointer == zero capcity
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:34
you'd then have to check if the pointer is null when reading capacity or len though
extra operation vs just reading the value from stack
also copying the 3 values on stack is really very fast on modern hardware (single digit nanoseconds)
anyway, at this point it becomes academic, I don't have language design degree, I'm just some guy doing Rust :)
Aleksey Kladov
@matklad
Dec 08 2016 14:36
But you'll have three times less data on the stack, and three times less data for empty vectors :) It's not obvious to me which would be more efficient.
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:44
@xialvjun I guess example with vec is easier on new people because you don't have to explain why you'd want to use a vec to begin with (a growable array-like thing is pretty common)
where as explaining why Box is useful from someone coming from a JS / Java / Ruby / Python would take a bit more
Aleksey Kladov
@matklad
Dec 08 2016 14:46
@xialvjun you might want to check the explanation in the new iteration of Rust book: http://rust-lang.github.io/book/ch04-01-what-is-ownership.html
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:46
stack and heap comes much later in the book
xialvjun
@xialvjun
Dec 08 2016 14:48
It's just an advice. It depends how the author think. And I'm going on to read the docs. @matklad I'll see it.
Maciej Hirsz
@maciejhirsz
Dec 08 2016 14:49
in general different examples will click with different people, it's definitely worth exploring which ones work best
writing the book is a pretty darn hard thing to do, it's quite impressive piece of work :)