我在某处读到snprintf比ostringstream快。有没有人有任何经验呢?如果是的话为什么它更快。为什么snprintf比ostringstream更快?或者它是什么?
回答
std::ostringstream
不是要求要慢一些,但实施时一般比较慢。 FastFormat's website has some benchmarks。
流的标准库设计支持远远超过snprintf
。该设计旨在具有可扩展性,并且包含由公开公开方法调用的方法。这允许你从一个流类派生出来,并保证如果你超载了protect
ed方法,你将得到你想要的行为。我相信编译器可以避免virtual
函数调用的开销,但我不知道有任何编译器。
此外,流操作通常在内部使用可增长的缓冲区;这意味着相对较慢的内存分配。
这很有可能是因为sprintf
是用汇编编写的CRT的一部分。 ostringstream
是STL的一部分,可能更通用一些,并且有OOP代码/开销来处理。
我非常强烈地怀疑有人在汇编中实现了`sprintf`,除了可能作为一个练习受虐狂。一直回到UNIX V6,C运行时库本身已经被编写成C语言(除了一些很少用C语言编写的东西,比如`setjmp`)。 – zwol 2012-09-19 15:42:09
绝对这是特定于实现的。
但是,如果你真的想知道,写两个小程序,并比较它们。您需要包含您想要的典型用法,这两个程序需要生成相同的字符串,然后使用分析器查看时序信息。
然后你就会知道。
我知道printf家族函数比相应的C++函数(cout,cin和其他流)快的原因之一是后者进行类型检查。由于这通常涉及一些重载操作员的请求,因此可能需要一些时间。实际上,在编程竞赛中,为了这个原因,通常建议您使用printf等而不是cout/cin。
有些人可能会告诉你,函数不能比彼此更快,但他们的实现可以。这是对的,我想我会同意。
除了基准以外,您不可能注意到其中的差异。 C++流一般趋于的原因是它们更加灵活。灵活性通常是以时间或代码增长为代价的。
在这种情况下,C++流基于流缓冲区。流本身就是保持格式化和错误标志的地方,并调用C++标准库的正确i/o
构面(例如,用于打印数字的num_put),将值格式化良好的值打印到基础流中连接到C++流的缓冲区。
所有这些机制 - 方面和缓冲区都是通过虚函数实现的。虽然确实没有标记请注意,这些函数必须被实现为比cStdio挂件慢,这实际上会使它们比通常使用c stdio函数稍慢(我基准了一段时间之前用gcc/libstdC++和事实上注意到一个放缓 - 但你几乎没有注意到在日常使用)。
有一个问题可能是由ostringstream
增加的类型安全带来额外的开销。不过,我还没有做过任何测量。
我们用sprintf(使用静态分配的缓冲区)替换了内部循环中的一些stringstream,这在msvc和gcc中都有很大的不同。我想,这个代码的动态内存管理:
{ char buf[100]; int i = 100; sprintf(buf, "%d", i); // do something with buf }
比
{ std::stringstream ss; int i = 100; ss << i; std::string s = ss.str(); // do something with s }
简单多了,但我很高兴与stringstreams的整体性能。
是的,如果你用Visual C++ 5.0在几百万个数字上运行下面的函数,第一个版本的时间大约是第二个版本的两倍,并产生相同的输出。
将紧密循环编译为.exe文件并运行Windows时,“我是如何调查大多数性能好奇心的。 (`timethis'可在网上找到)
void Hex32Bit(unsigned int n, string &result)
{
#if 0
stringstream ss;
ss
<< hex
<< setfill('0')
<< "0x" << setw(8) << n
;
result = ss.str();
#else
const size_t len = 11;
char temp[len];
_snprintf(temp, len, "0x%08x", n);
temp[len - 1] = '\0';
result = temp;
#endif
}
- 1. 什么是更快,为什么?
- 2. 为什么ostringstream strip NULL?
- 3. 什么比std :: pow更快?
- 4. 什么比innerHTML更快?
- 5. 流媒体?或者它是什么?
- 6. 恶意js?或者它是什么
- 7. REGEXP上这就是为什么或者这就是为什么
- 8. 回声为什么比打印更快?
- 9. 为什么BLE 4.2比BLE更快4.1
- 10. 为什么DataContract比Serializable更快?
- 11. 为什么Unix /终端比R更快?
- 12. 为什么order()比sort.list()更快?
- 13. 为什么Java StampedLock比ReentrantReadWriteLock更快
- 14. 为什么A *比Dijkstra更快
- 15. 为什么Neo4j比SQL更快
- 16. 为什么file_get_contents()比使用fsock_open()更快?
- 17. DataTable为什么比DataReader更快
- 18. 为什么Core Data比SQLite更快
- 19. 为什么String.IsNullOrEmpty比String.Length更快?
- 20. 为什么VertexBuffer比DynamicVertexBuffer更快
- 21. 为什么const int比const int&更快?
- 22. 为什么Crystal比Ruby更快?
- 23. 为什么ConcurrentHashMap :: putIfAbsent比ConcurrentHashMap :: computeIfAbsent更快?
- 24. 为什么array.index比array.include更快?
- 25. 为什么float()比int()更快?
- 26. Python:为什么*和**比/和sqrt()更快?
- 27. 为什么emplace_back比push_back更快?
- 28. 为什么DataContractSerializer比xmlSerializer更快?
- 29. 为什么\%(\)在Vim中比\(\)更快?
- 30. 为什么SQL函数比UDF更快
哇 - 我有一段时间没去过马修威尔逊的网站 - 看起来他过去几个月都很忙... – 2009-01-15 01:52:18
FastFormat测试是有偏见的。下载代码后,您会看到snprintf()基准测试会调用一个名为fastformat_util_snprintf()的函数,该函数包含一些可能会抛出测试的包装代码。但是你是对的,内存管理可能是ostringstream变慢的原因。 – Max 2009-01-16 11:13:26
感谢您查看代码。我只看过漂亮的图表。 – 2009-01-20 09:10:05