News for hackers. Stuff that matters.
Re:Why is Rust slightly slower than C? by comex on Wednesday September 11, 2019 @11:15PM (#20947566)
Indeed, RAII is a zero-cost abstraction compared to running the same destructors manually. On the other hand, C++ makes it really easy to write programs that copy and destroy things when it isn't necessary.

For example, if a function takes a `std::string` as an argument (by value), any string you pass in will be copied into a new allocation, which will then have to be deallocated. That's fine if the function really needs its own allocation – but it might not. In that case you can avoid the copy by changing the argument type to `const std::string &` or `std::string_view` (the latter being new in C++17)... but the difference is subtle enough that even an experienced programmer might not notice the extraneous copy.

Don't believe me? Consider that in 2014, "std::string was responsible for almost half of all allocations in the Chrome browser process"! [1]

(Rust does a better job here by requiring more explicitness if you want to make expensive copies.)

Oh, there's also an issue where the presence of a destructor pessimizes the calling convention for passing and returning objects of that type by value, but only slightly, and the issue will be addressed in the future. [2]

[1] https://groups.google.com/a/chromium.org/forum/#!msg/chromiu...

[2] https://quuxplusone.github.io/blog/2018/05/02/trivial-abi-10...

Re:Why is Rust slightly slower than C? by hendzen on Wednesday September 11, 2019 @11:28PM (#20947646)
even if you take the string as `const std::string &` you will still end up with implicit string construction if someone passes a char* . Sure you can use std::string_view as an argument type to prevent this simple case, but it doesn't work in all cases.

Consider a std::map<std::string, Blah> for example, if you have a char* and you want to index in to the map you are going to also end up with an intermediate string construction b/c STL associative containers don't have heterogenous lookup. Note that this was fixed in std::map::find in C++14 [0], but still is there for operator[].

[0] - https://en.cppreference.com/w/cpp/container/map/find

Re:Why is Rust slightly slower than C? by ncmncm on Thursday September 12, 2019 @12:46AM (#20948087)
This is obsolete and faulty advice.

Given a modern compiler and library, a by-value string temporary can be passed down a chain of calls with no allocations beyond the first, and returned, likewise.

Passing a reference means the optimizer cannot optimize accesses, because it doesn't know what other pointers might be aliasing it. string_view has the same problem.

Quotes about Chromium and Firefox are likewise obsolete. Old code, old coding standards. Neither uses RAII, so they pay a 20-30% runtime penalty. With a modern library, short strings do no allocation. (IIRC Firefox uses 16-bit characters, so they get less.)

That said, if the runtime performance of code trafficking in string objects matters, you are Doing It Wrong.

Re:Why is Rust slightly slower than C? by comex on Thursday September 12, 2019 @01:27AM (#20948305)
> Given a modern compiler and library, a by-value string temporary can be passed down a chain of calls with no allocations beyond the first, and returned, likewise.

For calls (as opposed to returns): If you use std::move, yes. Otherwise, no. But using std::move is similar to changing the type in that it requires noticing the problem first.

> Passing a reference means the optimizer cannot optimize accesses, because it doesn't know what other pointers might be aliasing it. string_view has the same problem.

For `const std::string &`, the optimizer has to assume that the string pointer and length could change, which is indeed a problem as it has to keep reloading them if you call, e.g., `c_str()` or `size()` multiple times (with other things in between). For both `const std::string &` and `std::string_view`, the optimizer has to assume that the string data could change, but not the pointer or length, which is much less of a problem because you don't usually repeatedly load the same piece of string data in a loop. Therefore, `std::string_view` is a decent choice.

Passing `std::string` by value does indeed have the advantage that the compiler indeed could theoretically assume the string data is not aliased. But I just checked and none of Clang, GCC, MSVC, or ICC actually do so:

https://gcc.godbolt.org/z/DZPsuU

Re:Why is Rust slightly slower than C? by ncmncm on Thursday September 12, 2019 @01:52AM (#20948429)
Again, doing it wrong is Doing It Wrong.

But moving can pessimize string-passing and -returning. Just write the code in the clearest way possible, and optimize hot paths where it turns out to matter, according to measurements. People have been demonstrated to be very poor at picking which those are, a priori.

Re:Why is Rust slightly slower than C? by codesushi42 on Thursday September 12, 2019 @09:28PM (#20958270)
Quotes about Chromium and Firefox are likewise obsolete

Yeah, because neither of those teams had any idea what they were doing, obviously. Even with C++ 11 at their disposal. But somehow, interestingly enough, you do.

Neither uses RAII, so they pay a 20-30% runtime penalty

Who knows where you pulled that number from.

I guess then, according to you at least, there are no performance penalties to be paid for any C++ language features. Please, continue to impart your knowledge and unreferenced benchmark tests on us all.