Hacker News new | past | comments | ask | show | jobs | submit login

Oh, agreed. But how about this:

    let x = BigExpensiveStruct::new();
    some_function(x);
That won't trigger a big, expensive memcpy of the BigExpensiveStruct, will it? I'd thought that its memory was on the heap.



If that's just a struct, it's stack allocated. So it's not ok the heap in the first place. IIRC, LLVM may optimize passing it to the function by reference though.


Good to know. Thanks! So I guess the moral is, if you have a big, expensive struct, make sure the expensive part is in a sub-structure you know is heap allocated, such as a Vec. E.g.:

    struct Expensive {
        cheap_value: u32,
        expensive_value: Vec<u32>
    }
Does that seem like a good maxim?


That is not a big expensive struct (to memcpy). (edit: I'm just bickering about what to call things, what you say is right.)

Your intuition about the performance of this sort of thing might be served by reading about how calling conventions work. You might not need to copy the struct from a local variable to where it belongs on the stack or in registers when calling a function, either because the calling convention says you put a pointer to the struct somewhere (depending on its size) or because you're (you being a compiler) clever enough to put it in the place that'll end up in the argument list later. The callee, however, has less flexibility, and if it needs to pass the value somewhere else, it'll probably have to copy the data. This is way better than allocating it on the heap -- stuff on the stack is in the L1 cache, you compute it's location statically instead of having to traverse data structures, but yeah if you found yourself copying around a 1000-byte struct you might want to box it or pass it by reference. I only know about C and C++ calling conventions though, so don't infer from my comment that Rust isn't doing anything "special" for big non-copyable structs -- I wouldn't know.


Rust (well, LLVM really) will automatically pass any "large" struct by reference, which in practice is going to be anything more than a few words (I think in the current implementation, it might actually be two). Unless the function call is inlined, of course, in which case LLVM can do pretty much whatever it wants.


Well, it depends. I mean, generally, you want to give flexibility to your users. Maybe I _do_ want to stack allocate an ExpensiveStruct for some reason. You can always Box the struct to have it on the heap.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: