对于字符串对象连接,stringstream是否比string的运算符'+'更好?

时间:2015-05-15 07:43:25

标签: c++ string

例如,我有两个字符串对象:string str_1,str_2。我想连接他们。我可以使用两种方法: 方法1:

std::stringstream ss;
//std::string str_1("hello");
//std::string str_2("world");
ss << "hello"<< "world";
const std::string dst_str = std::move(ss.str());

方法2:

std::string str_1("hello");
std::string str_2("world");
const std::string dst_str = str_1 + str_2;

因为字符串的缓冲区是只读的,所以当您更改字符串对象时,其缓冲区将销毁并创建一个新缓冲区以存储新内容。方法1比方法2好吗?我的理解是否正确?

3 个答案:

答案 0 :(得分:8)

与简单字符串相比,

stringstreams是复杂对象。你使用方法1的每一天都必须构造一个stringstream,然后再进行破坏。如果你这样做了数百万的时间,那么开销将远远不能忽视。

显然简单的ss << str_1 << str_2实际上等同于std::operator<<(sst::operator<<(ss, str_1), str_2);,它没有针对内存连接进行优化,但对于所有streams都是通用的。

我做了一个小基准测试:

  • 在调试模式下,方法2的速度几乎是method1的两倍。

  • 在优化构建中(在汇编程序文件中验证没有进行任何优化),它的速度提高了27倍。

答案 1 :(得分:0)

  • 方法2更适合您的情况。因为它可以降低stringstream obj创建的可读性和时间成本。
  • 但是,我强烈建议使用格式以提高可读性。维护,而不是“+”或其他字符串连接。

答案 2 :(得分:0)

适合所有人。也许我有点懒。现在我给了代码测试。

测试1:158.751ms,这么久,我的上帝!

    int main()
    {
        chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now();
        for(int i=0;i<100000;i++)
        {
            //string str_1("hello ");
            //string str_2("world");
            stringstream ss;
            ss << "hello " << "world";
            const string dst_str = ss.str();
        }
        chrono:: high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now();

        chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time);
        cout << "time takes " << slapsed.count() * 1000 << "ms" << endl;
        return 0;
    }

测试2:31.1946ms,最快!

    int main()
    {
        chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now();
        for(int i=0;i<100000;i++)
        {
            string str_1("hello ");
            string str_2("world");
            const string dst_str = str_1 + str_2;
        }
        chrono:: high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now();

        chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time);
        cout << "time takes " << slapsed.count() * 1000 << "ms" << endl;
        return 0;
    }

测试3:使用boost :: filesystem :: path 35.1769ms,也是一个不错的选择

    int main()
    {
        chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now();
        for(int i=0;i<100000;i++)
        {
            string str_1("hello ");
            string str_2("world");
            boost::filesystem::path dst_path(str_1);
            dst_path += str_2;
            const string dst = dst_path.string();
        }
        chrono::high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now();

        chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time);
        cout << "time takes " << slapsed.count() * 1000 << "ms" << endl;
        return 0;
   }