Live data from Hacker News

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

forrestthewoods.com

111–120 of 238 posts

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

#111
post #82

Earlier quoted context omitted.

edit: I misread the previous post. Ignore this. How are you using the word simpler? Because to me that implies a combination of more obvious and number of lines of code. Something that a benchmark shouldn't be involved in. For example asking someone to delete 10 lines of code and instead use go's ` net.SplitHostPort` would be an example of "simpler".

I've read that good generals worry about tactics and great generals worry about logistics. Good programmers play code golf, great programmers write readable and maintainable code. Your example seems reasonable but programmers also like to act like the smartest one in the room. I often come across tricky and borderline obfuscated code because somebody wanted to look clever. This is a logistical nightmare.

Ugh, you are right but then someone comes and uses this to rationalize not including things like map, filter and reduce in a language because they are supposedly too complicated and you can just do it with a for loop

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

#112

Earlier quoted context omitted.

The assumption behind such arguments is when a performance problem does arise, a profiler will point to a single, easy to fix, smoking gun. Unfortunately this is not always the case. Performance problems can be hard to diagnose and hard to fix. A lot of damage has been done by unexamined / dogmatic "root of all evil" mantra.

In the vast majority of situations (1) you'll prematurely optimize in the wrong place and (2) yes the profiler will point to a single, easy-to-fix smoking gun. Situations otherwise are the exception, rather than the rule, and it takes an expert to (1) recognize those situations and (2) know exactly how to write optimized code in that situation. That's why "don't prematurely optimize" is a good rule of thumb - because…

Suggest acquiring the needed knowledge instead of applying dogma. The true root of all evil is unexamined dogma.

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

#113

Earlier quoted context omitted.

In Rust it's considered idiomatic to pass things by-value whenever you can. Usually this is also the most performant option, since it avoids dereferencing in the callee. Of course, if your struct is truly enormous, you may want to break this rule to avoid large copies. But in that case you probably want to Box the struct anyway. Of course, if your struct contains something that can't be copied--like a Vec --you'll ha…

I don't think I'd agree that idioms come into play here, one way or the other. Safely borrowing things by reference is one of Rust's headline features

> Safely borrowing things by reference is one of Rust's headline features

Sure, but it's worth noting that references in Rust do not exist merely to avoid passing by-value. They also exist to make it easier to deal with Rust's ownership semantics: they let you pass things to a function without also requiring the function to "pass back" those things as returned values. In other words, references let you do `fn foo(x: &Bar)` rather than `fn foo(x: Bar) -> Bar`. This is a unique and interesting consequence of languages with by-default move semantics.

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

#114

It's compiled, so, without any investigation at all, I would have been disappointed if there were any significant difference in the code emitted in these cases. I would expect the compiler to do the efficient thing based on usage rather than the particular syntax. I may have too much faith in the compiler.

At the VERY end of the article, the author points out "Oh, btw, I used MSVC for the C++ compilation, when I used clang things changed!"

So, what the author actually measured was the difference between llvm and msvc throughout the article. Particularly when they talked about rust being better at autovectorization than C++.

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

#115

Earlier quoted context omitted.

I've read that good generals worry about tactics and great generals worry about logistics. Good programmers play code golf, great programmers write readable and maintainable code. Your example seems reasonable but programmers also like to act like the smartest one in the room. I often come across tricky and borderline obfuscated code because somebody wanted to look clever. This is a logistical nightmare.

Ugh, you are right but then someone comes and uses this to rationalize not including things like map, filter and reduce in a language because they are supposedly too complicated and you can just do it with a for loop

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.

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

#116
post #37

The benchmarks lack the standard deviation, so the results may well be equivalent. Don't roll your own micro-benchmark runners. References may get optimized to copies where possible and sound (i.e. blittable and const), a common heuristic involves the size of a cache line (64b on most modern ISAs, including x86_64). Using a Vector4 would have pushed the structure size beyond the 64b heuristic. You would also need to…

It was also (needlessly) using 2 different compilers, MSVC and LLVM. This is just a bad way to compare things all around.

And, for simple operations like this, you really should just look at the assembly output. If you are only generating 20ish instructions, then look at those 20 instructions rather than trying to heuristically guess what is happening.

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

#117

A potential lesson here (i.e. I am applying confirmation bias to retroactively view this article as justification for a strongly held opinion, lol): Unless you are gonna benchmark something, for details like this you should pretty much always just trust the damn compiler and write the code in the most maintainable way. This comes up in code review a LOT at my work: - "you can write this simpler with XYZ" - "but that…

This x 10000 ! If I had a dime for every time I provided this exact feedback in code reviews…I find surprising that a lot of devs in tech industry are obsessed with pointless micro optimizations and they don’t care about writing maintainable, testable simple code. My final comment is always to not outsmart compilers/jvm because they tend to do a much better job that developers.

Please, don’t optimize unless you have reasons to do so and numbers backing that up.

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

#118
post #78

I did the test on my computer: Rust - By-Copy: 14124, By-Borrow: 8150 C++ - By-Copy: 12160, By-Ref: 11423 P.S. Just built it using LLVM under CLion IDE and the results are: G:\temp\cpp\rust-cpp-bench\cpp\cmake\cmake-build- release\fts_cmake_cpp_bench.exe Totals: Overlaps: 220384338 By-Copy: 4397 By-Ref: 4396 Delta: -0.0227428% Process finished with exit code 0

How did you build it? It doesn't build with either gcc-12 or clang-15 on linux.

I built it on Windows, Visual C++ 2022. Did not check Linux as I do not think it matters much.

Now comes big surprise: I just built it using LLVM under CLion IDE and the results are:

  G:\temp\cpp\rust-cpp-bench\cpp\cmake\cmake-build- 
   release\fts_cmake_cpp_bench.exe
   Totals:
     Overlaps: 220384338
     By-Copy: 4397
     By-Ref: 4396  Delta: -0.0227428%

  Process finished with exit code 0

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

#119
post #86

Earlier quoted context omitted.

When value size is small (whatever "small" means for particular architecture) I'd say "trust the compiler" suggestion is reasonable. When the size grows there should be no more "trust" unless compiler can decipher if it is safe to use ref instead of value basing on value size (we assume that the function does not mutate the value). Your tests on my PC: Rust - By-Copy: 14124, By-Borrow: 8150 C++ - By-Copy: 12160, By-R…

> When the size grows there should be no more "trust" unless compiler can decipher if it is safe to use ref instead of value basing on value size I believe that the Rust compiler at least does exactly that. Large structs will be passed by reference under the hood even if it passed by value in the code. I suspect C++ compilers do the same, although I'm not sure about that.

Now comes big surprise: I just built it using LLVM under CLion IDE and the results are:

  G:\temp\cpp\rust-cpp-bench\cpp\cmake\cmake-build- 
   release\fts_cmake_cpp_bench.exe
   Totals:
     Overlaps: 220384338
     By-Copy: 4397
     By-Ref: 4396  Delta: -0.0227428%

  Process finished with exit code 0

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

#120

A potential lesson here (i.e. I am applying confirmation bias to retroactively view this article as justification for a strongly held opinion, lol): Unless you are gonna benchmark something, for details like this you should pretty much always just trust the damn compiler and write the code in the most maintainable way. This comes up in code review a LOT at my work: - "you can write this simpler with XYZ" - "but that…

I generally agree, but it’s also not obvious to me in Rust (or in Go) whether passing by reference or by copy is more maintainable or clear. I guess what I want is some guidance on what I should do by default, which you sort of give with “do what is more maintainable”, but I can’t tell what that means in practice (I’ve been told to default to pass-by-reference in the past because most traits take &self and not self).
Post reply on HN