// test code
void TestPerformance(const No2StringBuilder<wchar_t> &tested, const std::vector<std::wstring> &tested2) {
    const int loops = 4001; // Odd number to keep 1 result at the end.
    ////////////////
    // Test std::accumulate()
    ////////////////
    std::wstring accumulate_result;
    size_t accumulate_len = 0;
    StopWatch swAccumulate;
    for (int i = 0; i < loops; ++i) {
        std::wstring accumulator;
        accumulate_result = std::accumulate(tested2.begin(), tested2.end(), accumulator);
        accumulate_len ^= accumulate_result.size();
    }
    swAccumulate.Stop();
    using std::cout;
    using std::endl;
    cout << "\tstd::accumulate: " << swAccumulate.GetSeconds() << ": size " << accumulate_len << endl;
    ////////////////
    // Test ToString()
    ////////////////
    std::wstring toString_result;
    size_t toString_len = 0;
    StopWatch swToString;
    for (int i = 0; i < loops; ++i) {
        toString_result = tested.toString();
        toString_len ^= toString_result.size();
    }
    swToString.Stop();
    cout << "\tToString: " << swToString.GetSeconds() << ": size " << toString_len << endl;
    ////////////////
    // Test join()
    ////////////////
    std::wstring join_result;
    size_t join_len = 0;
    StopWatch swJoin;
    for (int i = 0; i < loops; ++i) {
        join_result = tested.join(L",");
        join_len ^= join_result.size();
    }
    swJoin.Stop();
    cout << "\tJoin: " << swJoin.GetSeconds() << ": size " << join_len << endl;
    
    ////////////////
    // basic_ostringstream<wchar_t>
    // First test: only getting the string, not filling the stream.
    ////////////////
    typedef std::basic_ostringstream<wchar_t> wostringstream;
    wostringstream woss;
    for(size_t j = 0; j < tested2.size(); ++j)
        woss << tested2[j];
    std::wstring stringStream_result;
    size_t stringStream_len = 0;
    StopWatch swStringStream;
    for (int i = 0; i < loops; ++i) {
        stringStream_result = woss.str();
        stringStream_len ^= stringStream_result.size();
    }
    swStringStream.Stop();
    cout << "\tostringstream: " << swStringStream.GetSeconds() << ": size " << stringStream_len << endl;
    
    ////////////////
    // Test lambda
    ////////////////
    
    std::wstring strAccumulator;
    size_t lambdaResult_len = 0;
    StopWatch swLambda;
    for (int i = 0; i < loops; ++i) {
        std::wstring strtmp;
        std::for_each(tested2.begin(), tested2.end(), [&](const std::wstring &s){ strtmp += s; });
        if (0 == i) {
            strAccumulator = strtmp;
        }
        lambdaResult_len ^= strtmp.size();
    }
    swLambda.Stop();
    cout << "\tLambda: " << swLambda.GetSeconds() << ": size " << lambdaResult_len << endl;
    
    ////////////////
    // Show results so far.
    ////////////////
    cout << "* Performance test:" << endl
    << "    Accumulate took " << swAccumulate.GetSeconds() << " seconds, and ToString() took " << swToString.GetSeconds() << " seconds." << endl
    << "    The relative speed improvement was " << ((swAccumulate.GetSeconds() / swToString.GetSeconds()) - 1) * 100 << "%" << endl
    << "    std::ostringstream took " << swStringStream.GetSeconds() << " with a relative speed improvement of "  << ((swAccumulate.GetSeconds() / swStringStream.GetSeconds()) - 1) * 100 << "% (winning, you say?)" << endl
    << "    lambda took " << swLambda.GetSeconds() << " with a relative speed improvement of "  << ((swAccumulate.GetSeconds() / swLambda.GetSeconds()) - 1) * 100 << "% (winning, you say?)" << endl
    << "    Join took " << swJoin.GetSeconds() << " seconds."
    << endl;
    
    ////////////////
    // basic_ostringstream<wchar_t> and tostring: fill and execute.
    ////////////////
    
    if (true) {
        size_t tmp = 0;
        typedef std::basic_ostringstream<wchar_t> wostringstream;
        StopWatch swStringStream2;
        for (int i = 0; i < loops; ++i) {
            wostringstream woss;
            for(size_t j = 0; j < tested2.size(); ++j)
                woss << tested2[j];
            /*
             for (auto iter = tested2.begin(); iter != tested2.end(); ++iter) {
             woss << *iter;
             }
             */
            tmp ^= woss.str().size();
        }
        swStringStream2.Stop();
        cout << "\tostringstream (fill and convert to string): " << swStringStream2.GetSeconds() << ", length " << tmp << endl;
    }
    if (true) {
        size_t tmp = 0;
        StopWatch swToString2;
        for (int i = 0; i < loops; ++i) {
            No2StringBuilder<wchar_t> test;
            test.addBack(tested2.begin(), tested2.end());
            tmp ^= test.toString().size();
        }
        swToString2.Stop();
        cout << "\tToString (fill and convert to string): " << swToString2.GetSeconds() << ", length " << tmp << endl;
    }
}