2

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

  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 磁盘上。

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

4

3 回答 3

5

我会使用 tee 输出流。做类似的事情(伪代码):

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

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

另请参阅如何组合输出流的答案,以便输出一次到达多个位置?

于 2012-09-15T23:59:59.023 回答
3

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


1在此处分析邪恶之前插入关于优化的强制性免责声明。

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

于 2012-09-15T23:55:28.190 回答
2

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

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

  1. 需要对涉及的表达式求值并执行 3 次转换。根据您实际执行的操作,这可能仍然相当快。
  2. 实际上创建和销毁多个流并为std::string. 我希望这是最慢的。
  3. 仍然创建一个流(实际上应该是 a std::ostringstream)并分配一些内存。在您的选择中,我希望它是最快的。

使用 ateebuf可能是最快的,至少,当它进行一些缓冲但只使用固定的 suze 数组时,缓冲区和流缓冲区指针数组都是如此。请注意,您需要重写sync()以及时处理缓冲区。

要确定您需要测量的实际性能!

于 2012-09-16T00:03:13.967 回答