我很好奇许多字符串连接的性能.在C++中阅读了Efficient string concatenation之后,我做了一些测试.但结果因编译器不同而不同.
这是我的代码.(代码中的计时器来自此处.)
#include#include #include #include template struct measure { template static typename TimeT::rep execution(F&& func, Args&&... args) { auto start = std::chrono::system_clock::now(); std::forward (func)(std::forward (args)...); auto duration = std::chrono::duration_cast< TimeT> (std::chrono::system_clock::now() - start); return duration.count(); } }; std::string strAppend(const std::string &s, int cnt) { std::string str; for (int i = 0; i < cnt; ++i) str.append(s); return str; } std::string strOp(const std::string &s, int cnt) { std::string str; for (int i = 0; i < cnt; ++i) str += s; return str; } std::string strStream(const std::string &s, int cnt) { std::ostringstream oss; for (int i = 0; i < cnt; ++i) oss << s; return oss.str(); } std::string strReserveAndOp(const std::string &s, int cnt) { std::string str; str.reserve(s.size() * cnt); for (int i = 0; i < cnt; ++i) str += s; return str; } std::string strReserveAndAppend(const std::string &s, int cnt) { std::string str; str.reserve(s.size() * cnt); for (int i = 0; i < cnt; ++i) str.append(s); return str; } int main() { const std::string s("Hello world!"); const int cnt = 1000000 * 5; std::cout << "ostringstream: " << measure<>::execution(strStream, s, cnt) << "ms" << std::endl; std::cout << "+= operator: " << measure<>::execution(strOp, s, cnt) << "ms" << std::endl; std::cout << "s.Append(): " << measure<>::execution(strAppend, s, cnt) << "ms" << std::endl; std::cout << "s.Reserve() & +=: " << measure<>::execution(strReserveAndOp, s, cnt) << "ms" << std::endl; std::cout << "s.Reserve() & s.Append(): " << measure<>::execution(strReserveAndAppend, s, cnt) << "ms" << std::endl; }
Ideone使用GCC 5.1进行测试得出结果:
ostringstream: 602ms += operator: 345ms s.Append(): 336ms s.Reserve() & +=: 224ms s.Reserve() & s.Append(): 225ms
其中ostringstream
最慢,reserve()
加速一点点.
但是,在Visual Studio 2015社区中运行相同的代码时,结果如下:
ostringstream: 4413ms += operator: 9319ms s.Append(): 8937ms s.Reserve() & +=: 8966ms s.Reserve() & s.Append(): 8815ms
只要注意相对速度,ostringstream
变得最快,reserve()
似乎没有加快.
那为什么会这样呢?编译器优化还是其他什么?
由于詹姆d.看起来我猜是正确的.将优化更改/Od
为/O2
.结果是:
ostringstream: 1098ms += operator: 362ms s.Append(): 356ms s.Reserve() & +=: 216ms s.Reserve() & s.Append(): 227ms
与GCC 5.1相同.