【发布时间】:2015-07-05 08:47:17
【问题描述】:
我正在尝试编写一些代码并说服自己按值传递,按引用传递(rvalue 和lvalue 引用)应该具有重要意义对性能的影响 (related question)。后来我想出了下面的这段代码,我认为性能差异应该是可见的。
#include <iostream>
#include <vector>
#include <chrono>
#define DurationTy std::chrono::duration_cast<std::chrono::milliseconds>
typedef std::vector<int> VectTy;
size_t const MAX = 10000u;
size_t const NUM = MAX / 10;
int randomize(int mod) { return std::rand() % mod; }
VectTy factory(size_t size, bool pos) {
VectTy vect;
if (pos) {
for (size_t i = 0u; i < size; i++) {
// vect.push_back(randomize(size));
vect.push_back(i);
}
} else {
for (size_t i = 0u; i < size * 2; i++) {
vect.push_back(i);
// vect.push_back(randomize(size));
}
}
return vect;
}
long d1(VectTy vect) {
long sum = 0;
for (auto& v : vect) sum += v;
return sum;
}
long d2(VectTy& vect) {
long sum = 0;
for (auto& v : vect) sum += v;
return sum;
}
long d3(VectTy&& vect) {
long sum = 0;
for (auto& v : vect) sum += v;
return sum;
}
int main(void) {
{
auto start = std::chrono::steady_clock::now();
long total = 0;
for (size_t i = 0; i < NUM; ++i) {
total += d1(factory(MAX, i % 2)); // T1
}
auto end = std::chrono::steady_clock::now();
std::cout << total << std::endl;
auto elapsed = DurationTy(end - start);
std::cerr << elapsed.count() << std::endl;
}
{
auto start = std::chrono::steady_clock::now();
long total = 0;
for (size_t i = 0; i < NUM; ++i) {
VectTy vect = factory(MAX, i % 2); // T2
total += d1(vect);
}
auto end = std::chrono::steady_clock::now();
std::cout << total << std::endl;
auto elapsed = DurationTy(end - start);
std::cerr << elapsed.count() << std::endl;
}
{
auto start = std::chrono::steady_clock::now();
long total = 0;
for (size_t i = 0; i < NUM; ++i) {
VectTy vect = factory(MAX, i % 2); // T3
total += d2(vect);
}
auto end = std::chrono::steady_clock::now();
std::cout << total << std::endl;
auto elapsed = DurationTy(end - start);
std::cerr << elapsed.count() << std::endl;
}
{
auto start = std::chrono::steady_clock::now();
long total = 0;
for (size_t i = 0; i < NUM; ++i) {
total += d3(factory(MAX, i % 2)); // T4
}
auto end = std::chrono::steady_clock::now();
std::cout << total << std::endl;
auto elapsed = DurationTy(end - start);
std::cerr << elapsed.count() << std::endl;
}
return 0;
}
我使用-std=c++11 选项在gcc(4.9.2) 和clang(trunk) 上对其进行了测试。
但是我发现 only 在使用 clang T2 编译时需要更多时间(一次运行,以毫秒为单位,755,924,752,750)。我还编译了-fno-elide-constructors 版本,但结果相似。
(更新:在 Mac OS X 上使用 Clang(主干)编译时,T1、T3、T4 的性能略有不同。)
我的问题:
- 理论上应用了哪些优化来弥补
T1、T2、T3之间的潜在性能差距? (你可以看到我在factory中也试图避免RVO。) - 在这种情况下,gcc 对
T2应用的可能优化是什么?
【问题讨论】:
标签: c++ performance c++11 pass-by-reference