Search code examples
c++stringconcatenation

Most optimized way of concatenation in strings


We always came across many situation on daily basis wherein we have to do tedious and very many string operations in our code. We all know that string manipulations are expensive operations. I would like to know which is the least expensive among the available versions.

The most common operations is concatenation(This is something that we can control to some extent). What is the best way to concatenate std::strings in C++ and various workarounds to speed up concatenation?

I mean,

std::string l_czTempStr;

1).l_czTempStr = "Test data1" + "Test data2" + "Test data3";

2). l_czTempStr =  "Test data1"; 
    l_czTempStr += "Test data2";
    l_czTempStr += "Test data3";

3). using << operator

4). using append()

Also, do we get any advantage of using CString over std::string?


Solution

  • Here is a small test suite:

    #include <iostream>
    #include <string>
    #include <chrono>
    #include <sstream>
    
    int main ()
    {
        typedef std::chrono::high_resolution_clock clock;
        typedef std::chrono::duration<float, std::milli> mil;
        std::string l_czTempStr;
        std::string s1="Test data1";
        auto t0 = clock::now();
        #if VER==1
        for (int i = 0; i < 100000; ++i)
        {
            l_czTempStr = s1 + "Test data2" + "Test data3";
        }
        #elif VER==2
        for (int i = 0; i < 100000; ++i)
        {
            l_czTempStr =  "Test data1"; 
            l_czTempStr += "Test data2";
            l_czTempStr += "Test data3";
        }
        #elif VER==3
        for (int i = 0; i < 100000; ++i)
        {
            l_czTempStr =  "Test data1"; 
            l_czTempStr.append("Test data2");
            l_czTempStr.append("Test data3");
        }
        #elif VER==4
        for (int i = 0; i < 100000; ++i)
        {
            std::ostringstream oss;
            oss << "Test data1";
            oss << "Test data2";
            oss << "Test data3";
            l_czTempStr = oss.str();
        }
        #endif
        auto t1 = clock::now();
        std::cout << l_czTempStr << '\n';
        std::cout << mil(t1-t0).count() << "ms\n";
    }
    

    On coliru:

    Compile with the following:

    clang++ -std=c++11 -O3 -DVER=1 -Wall -pedantic -pthread main.cpp

    21.6463ms

    -DVER=2

    6.61773ms

    -DVER=3

    6.7855ms

    -DVER=4

    102.015ms

    It looks like 2), += is the winner.

    (Also compiling with and without -pthread seems to affect the timings)