Почему "вставка" быстрее, чем "добавление" при заполнении строк?

Я хочу дополнить string в C++,

Первоначально, просто добавив \0 до конца строки напрямую.

paddingstr = "test";
for (int index = 0; index < 20000*1024; ++index){
    paddingstr += '\0';
}

Тогда я нахожу несколько способов достичь своей цели, и они

Я хочу знать, какой метод является наиболее эффективным. а потом я сравниваю их.

string paddingstr = "test";
__int64 before_run_t = GetTimeMs64();
string afterpadding = paddingstr.append(string(20000*1024, '\0'));
cout << "The run time of append is " << GetTimeMs64() - before_run_t << endl;

paddingstr = "test";
before_run_t = GetTimeMs64();
paddingstr.insert(paddingstr.end(), 20000*1024, '\0');
cout << "The run time of insert is " << GetTimeMs64() - before_run_t << endl;

paddingstr = "test";
before_run_t = GetTimeMs64();
for (int index = 0; index < 20000*1024; ++index){
    paddingstr += '\0';
}
cout << "The run time of adding is " << GetTimeMs64() - before_run_t << endl;

ostringstream ss;
before_run_t = GetTimeMs64();
ss << 't' << std::setw(20000*1024) << std::setfill('a') << '\0';
paddingstr = ss.str();
cout << "The run time of ostream is " << GetTimeMs64() - before_run_t << endl;

И результат

The run time of append is 60
The run time of insert is 3
The run time of adding is 8589
The run time of ostream is 2276

У меня вопрос, почему вставка самая быстрая?

Обновление: тестовые коды изменены с

ss << 't' << std::setw(20000*1024) << std::setfill('\0'); 
paddingstr = ss.str();

Потому что \0 заполнение после строки, и функция str() просто вернись t в paddingstrпоэтому результат теста не верный.

1 ответ

Решение

Вставка выполняется быстрее всего, потому что вы говорите, чтобы она добавляла 20 МБ нулей одновременно, и она может выделяться один раз. Добавить немного медленнее, потому что нужно выделить 20 МБ нулей, а затем скопировать их. Цикл медленный, потому что он должен постоянно перераспределять все больше и больше, что вы могли бы хотя бы частично исправить, если бы вы позвонили paddingstr.reserve(20000*1024 + paddingstr.size()) первый. И острингстрим медленный, потому что струнные потоки обычно медленны, плюс вы копируете в строку в конце.

Другие вопросы по тегам