【发布时间】:2019-09-29 16:18:10
【问题描述】:
根据我在网上阅读的内容,{fmt} 库应该比 e.g. 快得多。串流。
然而,我做了一些简单的基准测试(测量系统时间,见下面的代码),似乎 {fmt} 总是比例如慢。串流。我是不是搞错了?
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
【问题讨论】:
-
请注意,您不仅要对格式进行基准测试,还要对整个字符串连接进行基准测试。像这样的字符串连接将包含大量重新分配,这可能会掩盖
format调用的时间。 -
您可以将行更改为
fmt::format("{}Number {} is great!", result, numbers[i]));以避免字符串连接 -
您也每次都在构造一个新的 fmt::format ,但只构造一次 std::stringstream 。您应该在 for 循环内构造一个 std::stringstream,然后在循环内构造一个
result += ss.str();。 -
@Someprogrammerdude :绝对正确。我应该补充一点,最终我对对格式本身进行基准测试并不感兴趣,而是对找到添加格式化字符串的最有效方法感兴趣。然而,格式化本身似乎是最耗时的部分。
标签: c++ performance stringstream fmt