Live data from Hacker News

Should small Rust structs be passed by-copy or by-borrow? (2019)

forrestthewoods.com

181–190 of 238 posts

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#182
post #158

Earlier quoted context omitted.

Great. Should be easy to prove then.

Yup, we have a good benchmarking suite to make sure changes don't cause regressions and that optimization changes actually work. That said, I think asking a developer to write everything they do twice so that they can A/B test is overboard. You can come back and really aggressively optimize later, but I think the "default" should be the fast thing, rather than the slow & easy thing.

The idea is that the "default" is the easy thing, which is usually optimized by the compiler.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#183
post #179

Earlier quoted context omitted.

Yup, we have a good benchmarking suite to make sure changes don't cause regressions and that optimization changes actually work. That said, I think asking a developer to write everything they do twice so that they can A/B test is overboard. You can come back and really aggressively optimize later, but I think the "default" should be the fast thing, rather than the slow & easy thing.

If "performance really does matter" (in Fintech) then a developer surely can write everything twice or more.

We could, yeah. I'm sure you're capable of re-writing everything you do twice. It's just a huge waste of time.

You get just as much benefit by assigning a performance refactor to an engineer when needed vs literally halving or worse the whole teams productivity.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#184
post #115

Earlier 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.

I've seen cases where an iterator was better, but I've also seen gains from using an imperative loop with manual indexing. Loop conditions and the occasional assertion can be enough to elide bounds checks. (Though sometimes the compiler gets too paranoid about integer overflow.)

Most of the time you should just write whatever's clear/convenient but sometimes it's worth trying both and scrutinizing godbolt.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#186
post #180

Earlier 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…

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?

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#187
post #179

Earlier quoted context omitted.

Yup, we have a good benchmarking suite to make sure changes don't cause regressions and that optimization changes actually work. That said, I think asking a developer to write everything they do twice so that they can A/B test is overboard. You can come back and really aggressively optimize later, but I think the "default" should be the fast thing, rather than the slow & easy thing.

If "performance really does matter" (in Fintech) then a developer surely can write everything twice or more.

Time to market can matter in fintech as much as anywhere else.

Edit: also optimizations often interact with each other and you can't always benchmark all possible combinations, so sometime you do have to rely on experience or reasoning from first principles to decide if an optimisation is worth it or not.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#188

I always prefer by-borrow. That's because in the future this struct may become non-copy and that means some unnecessary refactoring. My thinking is a bit like "don't take ownership if not needed" - the "not needed" part is the most important thing. Don't require things that are not needed.

> don't take ownership if not needed

That's my approach too as a Rust newbie. Borrow by default and take ownership only when needed, for the best ergononmics.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#189

Earlier quoted context omitted.

Yup, we have a good benchmarking suite to make sure changes don't cause regressions and that optimization changes actually work. That said, I think asking a developer to write everything they do twice so that they can A/B test is overboard. You can come back and really aggressively optimize later, but I think the "default" should be the fast thing, rather than the slow & easy thing.

The idea is that the "default" is the easy thing, which is usually optimized by the compiler.

When you're writing in a language like Rust or C++, you know broadly what the compiler optimizes and what it probably won't. You do need to do the work yourself a lot of the time.

Re: Should small Rust structs be passed by-copy or by-borrow? (2019)

#190
post #180

Earlier quoted context omitted.

>"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…

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

Post reply on HN