Live data from Hacker News

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

forrestthewoods.com

131–140 of 238 posts

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

#131

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…

> but that will be slower because it's a copy/a function call/an indirect branch/a channel send/a shared memory access

I really dislike these takes. I see engineers optimize these cases and then go ahead and make two separate SQL queries that could be one, ruining any false optimization gains they got by lord know how many times.

Yeah, you can loop over that 100 element list twice doing basic computation if you want, it's not going to make a difference for many engineering workloads, but could make a big difference in readability.

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

#132
post #121

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

> But if you have ten thousand cuts you’re probably doomed. And those don’t show up cleanly in a flame graph. I am reminded of the lovely nanosecond/microsecond talk by Grace Hopper. If your code does a little bit of setup and then spends all of its time in a single hotspot, fine. But if your code is full of microsecond-suboptimal speed bumps, you can probably hide your hotspot altogether. And a flat-ish flame graph…

> There's a reason that ancient software running on ancient hardware is way more responsive & snappy than what we have today. Laziness.

Laziness in terms of using entirely inappropriate algorithms, sure.

Laziness in not microbenchmarking minutia? It shouldn't be. There's a limit on how much that can hurt you. I would say much less than a factor of ten, but let's go with 10x just for argument's sake. If you have a CPU that's 500x faster, and use easy code that's 10x slower, you're doing just fine. This is not the problem with modern unresponsiveness.

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

#133

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

[deleted]

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

#134
post #84
post #81

Earlier quoted context omitted.

How is that semantically different from Rust? in - regular function arguments inout - mut function arguments out - function return Is there any additional information that a compiler can infer from Ada’s parameter syntax?

The difference between passing by reference vs. by value is observable when comparing pointers to the original vs. to the argument. This difference may be unobservable in Ada though (not sure), so Ada would have more freedom choosing between the two.

[deleted]

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

#135

Earlier quoted context omitted.

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…

This is true for application code. But, Rust is trying to sell itself as a systems language and an embedded language and a language you can write kernel modules in. Memory budget matters in these cases.

If memory budget matters, you have a memory budget. So you should be measuring and you can actually tell where you need improvements.

But in practice what we see overwhelmingly is that people want to do this stuff but they aren't measuring, because measuring is boring whereas making the code more complicated to show off how much you think you know about optimisation is easy. Knock it off.

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

#136
post #30

I'm surprised he tested MSVC and Clang, and not GCC which usually generates faster code than those two.

Well, they are the two easily available compilers on Windows. And rustc vs clang should be the fair comparison as they both use llvm

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

#137

Earlier quoted context omitted.

This is true for application code. But, Rust is trying to sell itself as a systems language and an embedded language and a language you can write kernel modules in. Memory budget matters in these cases.

If memory budget matters, you have a memory budget. So you should be measuring and you can actually tell where you need improvements. But in practice what we see overwhelmingly is that people want to do this stuff but they aren't measuring, because measuring is boring whereas making the code more complicated to show off how much you think you know about optimisation is easy. Knock it off.

Then knock off trying to use Rust as a systems language. Linear types make refactoring this nearly impossible if it does become and issue.

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

#138

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…

My advice is the opposite: if you want to make performance justifications for code, you need a benchmarking suite. I have them for a lot of my projects. (Rust’s criterion is a delight). A good benchmark suite is a subtle thing to write - you want real world testing data, and benchmarks for a range of scenarios. The benchmarks should be run often. For some changes, I‘ll rerun my benchmarks multiple times for a single commit. I benchmark the speed of a few operations, serialisation size, wasm bundle size and some other things.

Having real benchmarking data is eye opening. It was shocking to me how much the wasm bundle size increased when I added serialisation code. The time to serialise / deserialise a big chunk of data for me is 0.5ms - so fast that it’s not worth more microoptimizations. Lots of changes I think will make the code slower have no impact whatsoever on performance. And my instincts are so often wrong. About 50% of microoptimizations I try either have no effect or make the code slightly slower. And it’s quite common for changes that shouldn’t change performance at all to cause significant performance regressions for unexpected reasons.

I’ve also learned how important “short circuit” cases can be for performance. Adding a single early check for the trivial case in a function can sometimes improve end to end performance by 15-20%, which in already well tuned code is massive.

Performance work is really fun. But if you do performance tuning without measuring the results, you’re driving blindfolded. You’re as likely to make your code worse as you are to make it better. Add benchmarks.

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

#139
post #94

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…

One neat thing here is that the compiler is aware of which types are `Copy` and not internally mutable (not contianing an `UnsafeCell`). For these types, passing `&T` and `T` are equivalent, so the compiler could just choose the faster option. Even if it's not smart enough to do that today, it could implement this optimization in the future. This could work even without inlining, since the Rust calling convention is…

It would be nice if Rust could do this, but it breaks backwards compatibility. Some existing code depends on pointer values of &T being equal or not equal.

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

#140

I just went through all of this when building a raytracer. * Sprinkling & around everything in math expressions does make them ugly. Maybe rust needs an asBorrow or similar? * If you inline everything then the speed is the same. * Link time optimizations are also an easy win. https://github.com/mcallahan/lightray

> Maybe rust needs an asBorrow or similar?

FWIW, the `Borrow`, `AsRef`, and `Deref` traits all exist to support different variants of this.

Post reply on HN