对多个流使用相同的字符串

Same string to multiple streams

本文关键字:字符串      更新时间:2023-10-16

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

  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;  
    

这些输出流中的一些或全部可以在RAM磁盘上。

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

我会使用tee输出流。执行类似(伪代码)的操作:

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

标准c++库中似乎没有任何东西可以做到这一点,但Boost有一个。

另请参阅"如何组成输出流,以便输出同时到达多个位置?"的答案?

尽管您不太可能看到任何一种方式的差异1,但选项#3听起来最合理:与第一个选项不同,它不会多次将ints转换为strings;与第二个选项不同,它不为其中间结果2分配和删除多个string对象。从可读性的角度来看,它看起来也最干净:没有重复的代码,输出看起来像输出,而不是串联。


1在这里插入一个关于在分析是邪恶的之前优化的强制性免责声明。

2小型字符串优化可能有助于支持它的系统(感谢Prætorian),但对中间对象的构造函数和析构函数调用不会消失。

这样做的"正确"方法是让一个流缓冲区写入多个目的地,并通过std::ostream使用这个流缓冲区。这样,代码看起来就像只写了一次,但字符被发送了多次。搜索"teebuf Dietmar"会发现同一主题的一些变体。

也要评论你的问题:三种选择中哪一种最快取决于你的确切表达方式:

  1. 需要评估所涉及的表达式并执行三次转换。根据你实际做的事情,这可能仍然相当快
  2. 实际上创建和销毁多个流,并为CCD_ 5进行多个分配。我想这会是最慢的
  3. 仍然创建一个流(实际上应该是std::ostringstream)并分配一些内存。在你的选择之外,我希望它是最快的

使用teebuf可能是最快的,至少当它进行一些缓冲但只使用固定的suze数组时,无论是对于缓冲区还是流缓冲区指针数组。请注意,您需要覆盖sync()才能及时处理缓冲区。

要确定实际性能,您需要进行测量!