如果性能是一个非常重要的考虑因素,考虑c ++ 0x是否合适?

bal*_*lki -1 c++ testing c++11

我写了一个简单的测试来检查c ++ 0x有多好.这是示例C++代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;
#ifndef __GXX_EXPERIMENTAL_CXX0X__
 #define emplace_back push_back
 #define auto typeof(vs.begin())
#endif
int main()
{
 vector<string> vs;
 string s;
 while(cin>>s)
 {
  vs.emplace_back(s);
 }
 sort(vs.begin(),vs.end());
 for(auto it = vs.begin();it != vs.end();++it)
 {
  cout << (*it) << endl;
 }
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是一个运行它的脚本

#!/bin/bash

inputFile=`mktemp`;
outputFile1=`mktemp`
outputFile2=`mktemp`

cat /dev/urandom | base64 > $inputFile 2> /dev/null &

echo "Generating Sample Input.. ${1:-10} seconds"
sleep ${1:-10}

export TOKILL=`pgrep -P $$ cat`
$(kill $TOKILL) 2> /dev/null > /dev/null

wc -l $inputFile
echo -e "\nTesting without --std=gnu++0x"
g++ Test.C -o old
time ./old < $inputFile > $outputFile1

echo -e "\nTesting with --std==gnu++0x"
g++ Test.C --std=gnu++0x -o new
time ./new < $inputFile > $outputFile2

diff $outputFile1 $outputFile2
rm $inputFile $outputFile1 $outputFile2
Run Code Online (Sandbox Code Playgroud)

在我测试的大部分时间里,C++ 03比c ++ 0x更好.这是一个示例输出.

Generating Sample Input.. 10 seconds
845645 /tmp/tmp.YMxZtrVeD0

Testing without --std=gnu++0x

real 0m12.437s
user 0m10.273s
sys 0m2.152s

Testing with --std==gnu++0x

real 0m12.452s
user 0m10.241s
sys 0m2.196s
Run Code Online (Sandbox Code Playgroud)

c ++代码是自我解释的.脚本生成一个等长的随机字符串,由临时文件中的换行符分隔.打印生成的文件中的行数.

我正在使用矢量和排序.Sort将使用std :: swap.使用rvalue引用和std :: move,代码应该更快?

我的g ++版本还可以 g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 .我会改回我的问题.如果性能是一个非常重要的考虑因素,考虑c ++ 0x是否合适?如果我进行测试的方式是错误的,我应该如何正确地找到答案.请提供一些例子.

Joh*_*itb 10

这完全失败了.你在这里做了什么:

  • std::string从堆上分配的未初始化的字符块初始化a .完全未定义的行为和泄漏如地狱.
  • 调用emplace_back(someotherstdstring),从而仍然复制std :: string.

你可能真正想做的是,emplace_back(somecharptr)但即便如此,这也将完全失败.只是这样做没有任何真正的区别

std::string s0("foo"); // emplace_back("foo")
std::string s1(s0); // emplace_back(s0)
std::string s2((std::string const&)s0); // push_back(s0)
Run Code Online (Sandbox Code Playgroud)

可以说,构造起来s0甚至更高效,因为s0已经知道字符串的长度,而第一个长度"foo"必须由构造函数计算std::string.

我建议首先考虑你在那里写的所有内容.重点emplace_back是避免构造一个对象只是为了传递它push_back并复制它.但是在你的情况下你已经有了一个对象,所以传递它并没有多大意义emplace_back.


Pup*_*ppy 5

呃,你改成了emplace_back然后emplace_back了一个左值?这不会有任何区别 - 它仍然是一个左值,你还在制作副本.在C++ 03中,std :: string几乎肯定会使用与rvalue引用一样好的交换 - 移动语义只是更通用.现代标准库已经对某些类使用称为交换优化的东西,这些类模仿了在某些条件下rvalue引用的影响,包括向量调整大小.

结论:您已经在整个C++世界中选择了最优化,专业且专注的代码.这段代码实际上已经在它下面应用了移动语义,你不会在任何地方使用任何实际的rvalues.右值参考如何有所作为?