I don't know much about this, but by-copy sounds nice. I'd rather own stuff and be happy.
Should small Rust structs be passed by-copy or by-borrow? (2019)
211–220 of 238 posts
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#212Earlier quoted context omitted.
Blog author here. I somewhat agree, somewhat disagree. This line makes me uneasy: > I always ask them to either prove it or write the simple thing. If the code in question isn't hot enough to bother benchmarking it, the performance benefits probably aren't worth it _even if they exist_. One of my philosophies is that death by a thousand cuts is fine, but death by ten thousand cuts isn’t. A team of 10 engineers can pr…
Very little of your code is in hot loops. If the code that takes half a millisecond per frame could be twice as fast, but the hot loop is very optimized, then it doesn't really matter. And that's what I would think of by default for having many many cuts. Better to spend the optimization effort elsewhere. > shared_ptr is a canonical example of death by ten thousand cuts Why does that count as ten thousand cuts rather…
Very few programs have "hot loops" as small, contained things. "hot loops" is at this point as much of a bad trope as "but premature optimizations!" is.
> Why does that count as ten thousand cuts rather than one cut? That doesn't sound intractable to fix if you have months.
Why spend months re-writing code you could have just written correctly the first time if a single person had spent an hour messing around with benchmarks to figure out the proper guidance?
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#213Earlier quoted context omitted.
> This is one advantage of Ada, where parameters are abstractly declared as "in" or "in out" or "out". Also Fortran has "in", "inout" and "out".
C++23 is not too late to the party https://en.cppreference.com/w/cpp/memory/out_ptr_t/out_ptr
Herb made a proposal for proper in/out parameters for C++ in 2020 https://youtu.be/6lurOCdaj0Y
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#214Earlier quoted context omitted.
Why is performance so much better in this case? That seems like a suspiciously large delta from the first test. Were the other benchmarks run in debug mode / with optimizations turned off or something like that? What compiler & flags are you using?
>"Were the other benchmarks run in debug mode / with optimizations turned off or something like that?" Why would I do something like that? Of course all builds are release mode, optimize for speed. Rust - Windows - By-Copy: 14124, By-Borrow: 8150 C++ - Windows MS Compiler - By-Copy: 12160, By-Ref: 11423 C++ - Windows LLVM 15 - By-Copy: 4397, By-Ref: 4396 >"Why is performance so much better in this case?" Not sure and…
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#215Earlier quoted context omitted.
Very little of your code is in hot loops. If the code that takes half a millisecond per frame could be twice as fast, but the hot loop is very optimized, then it doesn't really matter. And that's what I would think of by default for having many many cuts. Better to spend the optimization effort elsewhere. > shared_ptr is a canonical example of death by ten thousand cuts Why does that count as ten thousand cuts rather…
> Very little of your code is in hot loops. Very few programs have "hot loops" as small, contained things. "hot loops" is at this point as much of a bad trope as "but premature optimizations!" is. > Why does that count as ten thousand cuts rather than one cut? That doesn't sound intractable to fix if you have months. Why spend months re-writing code you could have just written correctly the first time if a single per…
If you say so. I can pretty easily and meaningfully divide my current program into "happens once per frame or less" and "happens hundreds or more times in a row".
> Why spend months re-writing code you could have just written correctly the first time if a single person had spent an hour messing around with benchmarks to figure out the proper guidance?
If they could have figured it out that easily I understand even less how this example works.
Let me put it this way: If a benchmark can change huge swaths of significantly performance important code, then it's "hot enough to bother" by orders of magnitude. I thought we were talking about microbenchmarks for individual cuts!
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#216Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#217The cost of by-value lies in memory copies, while the cost of by-reference lies in dereferencing pointers where the values are needed, which might mean many more memory reads are needed than with by-value (depends on what you're doing). So it's just hard to tell which will do better in general -- there's no answer to that.
For a library, maybe providing by-value and by-reference interfaces should be good (except that will bloat the library). For everything else just use by-value as it has the best ergonomics.
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#218Earlier quoted context omitted.
I work in a Rust codebase that uses a lot of functional functions, and I’ll say this: on average the imperative style takes less lines of code and less indentation. I also find it more readable personally, and idiomatic.
Just because we’re on the topic of performance: the rust optimizer can sometimes generate better code if you use map / filter / etc. The slice iterator in any context is a huge win over manual array iteration because it only needs to do bounds checking once. Javascript (v8, last I checked) is the opposite. Simple for loops almost always outperform anything else.
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#219Earlier quoted context omitted.
Just because we’re on the topic of performance: the rust optimizer can sometimes generate better code if you use map / filter / etc. The slice iterator in any context is a huge win over manual array iteration because it only needs to do bounds checking once. Javascript (v8, last I checked) is the opposite. Simple for loops almost always outperform anything else.
This is premature optimization imo. Unless you’re using par_iter
It’s also much easier to stick to for() loops in javascript as you code than it is to rewrite everything later when tuning for performance. If that’s something you expect to need to do.
Re: Should small Rust structs be passed by-copy or by-borrow? (2019)
#220Earlier quoted context omitted.
I just updated Visual Studio 2022 with all the latest updates and installed the Clang toolchain. I also updated Rust to latest. C++ MSVC: By-Copy: 12,077 By-Ref: 11,901 C++ Clang: By-Copy: 5,020 By-Ref: 5,029 Rust: By-Copy: 3,173 By-Borrow: 3,148 All on Windows, and on the same i7-8700k desktop I used for the original post in 2019. Your Rust numbers are particularly curious. Maybe run `rustup update` and try again?
Just did this rustup update. Much better now. So the finals are: Rust - By-Copy: 2685, By-Borrow: 2694 C++ - Windows MS Compiler - By-Copy: 12160, By-Ref: 11423 C++ - Windows LLVM 15 - By-Copy: 4397, By-Ref: 4396 My CPU is AMD Ryzen 5950X so it seems like Rust kicks the shit out of C++ in this case. I am going to try LLVM 16 and GCC tomorrow. Happy New Year
rustc 1.58 (LLVM 13): By-Copy: 10804, By-Borrow: 7198
rustc 1.64 (LLVM 14): By-Copy: 7385, By-Borrow: 7328
rustc 1.66 (LLVM 15): By-Copy: 2667, By-Borrow: 2777
clang++ (LLVM 14): By-Copy: 2439, By-Ref: 2589
clang++ (LLVM 15): By-Copy: 2473, By-Ref: 2556
When compared with the same LLVM version clang much better utilised LLVM-14 than rustc - C++ is 3x faster. With LLVM-15 they are much closer.