(I've asked a similar question on SO but unfortunately it might not be proper, so I also put here; please kindly point out if you think it's a duplicate.)
I've heard many words about the move semantics (essentially rvalue) introduced in C++11. In theory, it should bring much performance improvement due to the fact it avoids unnecessary copies.
However, there have already been some optimizations for legacy code during compilation to deal with the inefficient temporary copies, such as:
- (named) return value optimizations
- constructor copy elision
And additionally for frequently used data structures, some C++ standard libraries use special optimizations (e.g., small string optimization for std::string
).
More importantly, although some pieces of legacy code are really inefficient they don't result in much latency since they are
- not frequently invoked
- modern computers have enough physical memories for them
So I'm asking: are there real-world examples that greatly accelerate the performance when using modern C++ (C++11/14/17) syntax, or improve the performance by a reasonable percentage (e.g., >10%) overall?
I expect that the answer can be any of the 3 categories:
#include <vector>
using std::vector;
using std::size_t;
size_t const MAX = NNN; // NNN is specified by -DNNN=xxx option
size_t const NUM = NNN/100;
vector<int> factory(size_t size) {
vector<int> v;
for (size_t i = 0u; i < size; ++i) {
v.push_back(i);
}
return v;
}
// Version 1
/// void doubles(vector<int> & v) {
// Version 2
void doubles(vector<int> && v) {
for (size_t i = 0u; i < v.size(); ++i) {
v[i] = v[i] * 2;
}
}
int main() {
// Version 1
/// vector<int> v = factory(MAX);
/// doubles(v);
// Version 2
doubles(factory(MAX));
}
- Some performance bugs/bottlenecks existing in real world repositories that can be handled modern C++ well.
- Some profiling for a piece of code that show the improvement.
- Starting by modifying some of the above trivial code to help me get an example that can bring the performance benefit.
And the improvement can still be viewed with default
(e.g., -O0
) compilation options (so -fno-elide-constructors
is not allowed during compilation) by gcc or
clang or
MSVC.
I ask this question because I was doing a survey on the move semantics impact on performance for real world programs but after I tried some (trivial) code and did some basic profiling myself, I found that I simply cannot find the significant differences. So please forgive me if you feel it stupid/pedantic.