#include <iostream>
#include <sstream>
#include <string>
#include <chrono>
template<typename TimeT = std::chrono::milliseconds>
struct measure {
template<typename F, typename ...Args>
static typename TimeT::rep execution(F&& func, Args&&... args) {
auto start = std::chrono::system_clock::now();
std::forward<decltype(func)>(func)(std::forward<Args>(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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGNocm9ubz4KCnRlbXBsYXRlPHR5cGVuYW1lIFRpbWVUID0gc3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcz4Kc3RydWN0IG1lYXN1cmUgewogICAgdGVtcGxhdGU8dHlwZW5hbWUgRiwgdHlwZW5hbWUgLi4uQXJncz4KICAgIHN0YXRpYyB0eXBlbmFtZSBUaW1lVDo6cmVwIGV4ZWN1dGlvbihGJiYgZnVuYywgQXJncyYmLi4uIGFyZ3MpIHsKICAgICAgICBhdXRvIHN0YXJ0ID0gc3RkOjpjaHJvbm86OnN5c3RlbV9jbG9jazo6bm93KCk7CiAgICAgICAgc3RkOjpmb3J3YXJkPGRlY2x0eXBlKGZ1bmMpPihmdW5jKShzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgICAgIGF1dG8gZHVyYXRpb24gPSBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDwgVGltZVQ+CiAgICAgICAgICAgIChzdGQ6OmNocm9ubzo6c3lzdGVtX2Nsb2NrOjpub3coKSAtIHN0YXJ0KTsKICAgICAgICByZXR1cm4gZHVyYXRpb24uY291bnQoKTsKICAgIH0KfTsKCnN0ZDo6c3RyaW5nIHN0ckFwcGVuZChjb25zdCBzdGQ6OnN0cmluZyAmcywgaW50IGNudCkgewogICAgc3RkOjpzdHJpbmcgc3RyOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjbnQ7ICsraSkKICAgICAgICBzdHIuYXBwZW5kKHMpOwogICAgcmV0dXJuIHN0cjsKfQoKc3RkOjpzdHJpbmcgc3RyT3AoY29uc3Qgc3RkOjpzdHJpbmcgJnMsIGludCBjbnQpIHsKICAgIHN0ZDo6c3RyaW5nIHN0cjsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY250OyArK2kpCiAgICAgICAgc3RyICs9IHM7CiAgICByZXR1cm4gc3RyOwp9CgpzdGQ6OnN0cmluZyBzdHJTdHJlYW0oY29uc3Qgc3RkOjpzdHJpbmcgJnMsIGludCBjbnQpIHsKICAgIHN0ZDo6b3N0cmluZ3N0cmVhbSBvc3M7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGNudDsgKytpKQogICAgICAgIG9zcyA8PCBzOwogICAgcmV0dXJuIG9zcy5zdHIoKTsKfQoKc3RkOjpzdHJpbmcgc3RyUmVzZXJ2ZUFuZE9wKGNvbnN0IHN0ZDo6c3RyaW5nICZzLCBpbnQgY250KSB7CiAgICBzdGQ6OnN0cmluZyBzdHI7CiAgICBzdHIucmVzZXJ2ZShzLnNpemUoKSAqIGNudCk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGNudDsgKytpKQogICAgICAgIHN0ciArPSBzOwogICAgcmV0dXJuIHN0cjsKfQoKc3RkOjpzdHJpbmcgc3RyUmVzZXJ2ZUFuZEFwcGVuZChjb25zdCBzdGQ6OnN0cmluZyAmcywgaW50IGNudCkgewogICAgc3RkOjpzdHJpbmcgc3RyOwogICAgc3RyLnJlc2VydmUocy5zaXplKCkgKiBjbnQpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjbnQ7ICsraSkKICAgICAgICBzdHIuYXBwZW5kKHMpOwogICAgcmV0dXJuIHN0cjsKfQoKaW50IG1haW4oKQp7CiAgICBjb25zdCBzdGQ6OnN0cmluZyBzKCJIZWxsbyB3b3JsZCEiKTsKICAgIGNvbnN0IGludCBjbnQgPSAxMDAwMDAwICogNTsKICAgIHN0ZDo6Y291dCA8PCAib3N0cmluZ3N0cmVhbTogIiA8PCBtZWFzdXJlPD46OmV4ZWN1dGlvbihzdHJTdHJlYW0sIHMsIGNudCkgPDwgIm1zIiA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgIis9IG9wZXJhdG9yOiAiIDw8IG1lYXN1cmU8Pjo6ZXhlY3V0aW9uKHN0ck9wLCBzLCBjbnQpIDw8ICJtcyIgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8ICJzLkFwcGVuZCgpOiAiIDw8IG1lYXN1cmU8Pjo6ZXhlY3V0aW9uKHN0ckFwcGVuZCwgcywgY250KSA8PCAibXMiIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAicy5SZXNlcnZlKCkgJiArPTogIiA8PCBtZWFzdXJlPD46OmV4ZWN1dGlvbihzdHJSZXNlcnZlQW5kT3AsIHMsIGNudCkgPDwgIm1zIiA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgInMuUmVzZXJ2ZSgpICYgcy5BcHBlbmQoKTogIiA8PCBtZWFzdXJlPD46OmV4ZWN1dGlvbihzdHJSZXNlcnZlQW5kQXBwZW5kLCBzLCBjbnQpIDw8ICJtcyIgPDwgc3RkOjplbmRsOwp9