当前位置:  开发笔记 > 编程语言 > 正文

连接多个字符串时,为什么性能会有所不同?

如何解决《连接多个字符串时,为什么性能会有所不同?》经验,为你挑选了1个好方法。

我很好奇许多字符串连接的性能.在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()似乎没有加快.

那为什么会这样呢?编译器优化还是其他什么?



1> Jaege..:

由于詹姆d.看起来我猜是正确的.将优化更改/Od/O2.结果是:

ostringstream: 1098ms
+= operator: 362ms
s.Append(): 356ms
s.Reserve() & +=: 216ms
s.Reserve() & s.Append(): 227ms

与GCC 5.1相同.


我认为这是我的问题的答案.
推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有