Почему {fmt} медленнее, чем std::stringstream?
Из того, что я прочитал в Интернете, предполагается, что библиотека fmt будет намного быстрее, чем, например, строковые потоки.
Однако я провел несколько простых тестов (измерение системного времени, см. Код ниже), и мне кажется, что fmt всегда медленнее, чем, например, stringstreams. Я что-то не так понимаю?
uint64_t start;
uint64_t stop;
long MAXCOUNT = 10000000;
std::srand(123);
int* numbers = new int[MAXCOUNT];
for ( int i = 0; i < MAXCOUNT; i++) {
numbers[i] = std::rand();
}
{
std::string result;
start = currentTimeInMillis();
for ( int i = 0; i < MAXCOUNT; i++) {
result += fmt::format("Number {} is great!", numbers[i]);
}
stop = currentTimeInMillis();
fmt::print("timing fmt : {} ms / string length: {}\n", stop-start, result.size());
}
{
std::string result;
std::stringstream ss;
start = currentTimeInMillis();
for ( int i = 0; i < MAXCOUNT; i++) {
ss << "Number " << numbers[i] << " is great!";
}
result = ss.str();
stop = currentTimeInMillis();
fmt::print("timing stds: {} ms / string length: {}\n", stop-start, result.size());
}
Типичный результат (уровень оптимизации O3 - меньше значит еще хуже) этого кода:
timing fmt : 1414 ms / string length: 264823200
timing stds: 1287 ms / string length: 264823200
1 ответ
Решение
Во-первых, у меня на машине разные числа. fmt
быстрее:
timing fmt : 1713 ms / string length: 264825935
timing stds: 2483 ms / string length: 264825935
Во-вторых, чтобы получить справедливое сравнение, замените
result += fmt::format("Number {} is great!", numbers[i]);
с
fmt::format_to(std::back_inserter(result), "Number {} is great!", numbers[i]);
Это улучшает синхронизацию (снова на моей машине)
timing fmt : 1153 ms / string length: 264825935
timing stds: 2482 ms / string length: 264825935