std::to_string与stringstream的区别

6
下面的代码展示了两种解决方案(std::to_stringstd::stringstream),用于将int类型的m_currentSoundTime转换为std::string。那么,std::to_stringstd::stringstream哪个更快呢?
// Compute current sound time in minute and convert to string
stringstream currentTime;
currentTime << m_currentSoundTime / 60;
m_currentSoundTimeInMinute =  currentTime.str();

或者

m_currentSoundTimeInMinute = to_string( m_currentSoundTime / 60 );

15
你的分析器告诉你什么? - Mike Seymour
3
和大多数依赖于实现的性能问题一样,正确答案是“测量并找出”。如果实际测量的工作不值得去做,那么优化的努力也可能不值得。 - utnapistim
"优化可能并不值得努力": 我更倾向于说"优化可读性"。 - mdup
2个回答

7
在任何一个合理的库实现中,对于这个问题,to_string的速度至少与stringstream相同。但是,如果您想把10个整数放进一个字符串里面,stringstream通常会更快。 如果您执行to_string(a) + ", " + to_string(b) + /*...*/,每次操作可能都会导致从先前字符串到新分配的内存的分配和复制——而 stringstream 则不会出现这种情况。
更重要的是,从您的示例代码可以明显看出,对于将单个int转换为字符串,to_string更加简洁清晰。

1
我认为这是扯淡 ;) 你忽略了移动语义的作用。to_string(a) 返回一个临时对象,可以通过 + ", " 进行修改,它本身也返回一个临时对象... 因此,实际上,使用 to_string 进行链式调用可能会更快(没有 virtual 分发等). - Matthieu M.
9
@MatthieuM。是的,但to_string(a) 的临时结果可能只有足够容纳当前内容的 capacity。所以当您执行 + "," 时,即使您不需要额外的 string 临时变量,当前 string 持有的分配空间也需要重新制作得更大,旧数据复制到新的分配中,等等。每个+都要重复这个过程。该实现可以(应该)使用realloc... 但仍会存在同样的问题,不一致的问题。 - David
实际上,该实现不太可能具有严格的容量(更可能包含足够的空间以容纳最小整数)。此外,std::string 应该使用平摊分配。当然,这可能会导致一两次重新分配……但无法确定是否比 std::stringstream 更多,并且不要忘记 std::stringstream::str() 会分配一个 string(如果需要的话)。 - Matthieu M.
我同意Mike Seymoure的观点:“你的分析器告诉你什么?”我以前进行过分析,David是正确的。对于多个转换,请使用ostringstream,对于单个转换,请使用to_string。ostringstream的昂贵部分是它的构造,之后就很便宜了。对于单个转换,to_string至少与ostringstream一样快,而且更少的样板文件。 - ericcurtin

5

这篇博客文章测试了几种将整数转换为字符串的方法(在Ubuntu 13.04上使用GCC 4.7)。在这种情况下,to_stringstringstream稍微慢一些。但这可能严重取决于编译器和std库。


我查看了libc++中to_string的实现,它只是委托给了snprintf。这样更简单,但确实令人惊讶。 - Matthieu M.
1
在这种情况下,to_string 比 stringstream 稍微慢一些。在博客文章中,to_string 比 stringstream 更快。我有什么地方理解错了吗? - Tamilselvan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接