与多个流相同的字符串

时间:2012-09-15 23:46:15

标签: c++ performance stl stream c++11

我必须向多个流发送相同的字符串(例如日志消息) 以下哪种解决方案效率最高?

  1. 为每个流重建相同的字符串,并将其发送到流本身。

    outstr1 << "abc" << 123 << 1.23 << "def" << endl;  
    outstr2 << "abc" << 123 << 1.23 << "def" << endl;  
    outstr3 << "abc" << 123 << 1.23 << "def" << endl;  
    
  2. 使用字符串的运算符构建字符串一次,并将其发送到所有流。

    std::string str = "abc" + std::to_string(123) + std::to_string(1.23) + "def";  
    outstr1 << str;  
    outstr2 << str;  
    outstr3 << str;  
    
  3. 使用流构建字符串一次,并将其发送到所有流:

    std::stringstream sstm;  
    sstm << "abc" << 123 << 1.23 << "def" << endl;  
    std::string str = sstm.str();  
    outstr1 << str;  
    outstr2 << str;  
    outstr3 << str;  
    
  4. 部分或全部这些输出流可能位于RAM磁盘上。

    还有其他方法可以做同样的事情吗?

3 个答案:

答案 0 :(得分:5)

我会使用tee输出流。做一些像(伪代码):

allstreams = tee(outstr1, outstr2, outstr3);
allstreams << "abc" << 123 << 1.23 << "def" << endl;

标准c ++库中似乎没有任何内容可以执行此操作,但Boost has one

另见How can I compose output streams, so output goes multiple places at once?

的答案

答案 1 :(得分:3)

虽然你不太可能在 1 中看到很多不同,但选项#3听起来最合理:与第一个选项不同,它不会将int转换为{{ 1次}多次;与第二个选项不同,它不为其中间结果 2 分配和删除多个string个对象。从可读性的角度来看,它看起来也是最干净的:没有代码重复,输出看起来像输出,而不是连接。


1 在此处描述为邪恶之前插入有关优化的强制免责声明。

2 Small String Optimization可能对支持它的系统有所帮助(感谢,Prætorian),但构造函数和析构函数对中间对象的调用不会消失。 / p>

答案 2 :(得分:2)

执行此类操作的“正确”方法是将流缓冲区写入多个目标,并通过std::ostream使用此流缓冲区。这样代码看起来好像只写了一次但字符被多次发送。搜索“teebuf Dietmar”会发现同一主题的一些变化。

还要对你的问题发表评论:三种选择中哪一种最快取决于你所拥有的确切表达方式:

  1. 需要评估所涉及的表达式并执行三次转换。根据你的实际情况,这可能仍然相当快。
  2. 实际上创建并销毁多个流并为std::string执行多个分配。我希望这是最慢的。
  3. 仍然会创建一个流(实际上应该是std::ostringstream)并分配一些内存。出于你的选择,我希望它是最快的。
  4. 使用teebuf可能是最快的,至少当它进行一些缓冲但只使用固定的suze数组时,缓冲区和流缓冲区指针数组都是如此。请注意,您需要覆盖sync()以及时处理缓冲区。

    确定您需要衡量的实际表现!