我必须向多个流发送相同的字符串(例如日志消息)
以下哪种解决方案最有效?
-
为每个流重新生成相同的字符串,并将其发送到流本身。
outstr1 << "abc" << 123 << 1.23 << "def" << endl; outstr2 << "abc" << 123 << 1.23 << "def" << endl; outstr3 << "abc" << 123 << 1.23 << "def" << endl;
-
使用字符串的运算符构建一次字符串,并将其发送到所有流。
std::string str = "abc" + std::to_string(123) + std::to_string(1.23) + "def"; outstr1 << str; outstr2 << str; outstr3 << str;
-
使用流构建一次字符串,并将其发送到所有流:
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听起来最合理:与第一个选项不同,它不会多次将int
s转换为string
s;与第二个选项不同,它不为其中间结果2分配和删除多个string
对象。从可读性的角度来看,它看起来也最干净:没有重复的代码,输出看起来像输出,而不是串联。
1在这里插入一个关于在分析是邪恶的之前优化的强制性免责声明。
2小型字符串优化可能有助于支持它的系统(感谢Prætorian),但对中间对象的构造函数和析构函数调用不会消失。
这样做的"正确"方法是让一个流缓冲区写入多个目的地,并通过std::ostream
使用这个流缓冲区。这样,代码看起来就像只写了一次,但字符被发送了多次。搜索"teebuf Dietmar"会发现同一主题的一些变体。
也要评论你的问题:三种选择中哪一种最快取决于你的确切表达方式:
- 需要评估所涉及的表达式并执行三次转换。根据你实际做的事情,这可能仍然相当快
- 实际上创建和销毁多个流,并为CCD_ 5进行多个分配。我想这会是最慢的
- 仍然创建一个流(实际上应该是
std::ostringstream
)并分配一些内存。在你的选择之外,我希望它是最快的
使用teebuf
可能是最快的,至少当它进行一些缓冲但只使用固定的suze数组时,无论是对于缓冲区还是流缓冲区指针数组。请注意,您需要覆盖sync()
才能及时处理缓冲区。
要确定实际性能,您需要进行测量!