c++ - 使用 stringstreams 加速 std::cout 日志记录
问题描述
我正在尝试加快一个多线程程序的速度,该程序可以打印很多std::cout
. 打印的大部分内容都是由多个变量(字符串、数字等)拼凑而成的字符串。访问std::cout
受互斥体保护,以防止来自多个线程的打印输出以以下方式混合:
{
std::lock_guard<std::mutex> lock(mutex);
std::cout << stringA << " 1 " << 5 << 'C' << std::endl;
}
测量结果表明,多个线程花费大量时间等待互斥体,std::cout
而对于大而复杂的字符串似乎需要一些时间。
我现在的问题是:
理论上我可以通过std::stringstream
在进入互斥锁之前将字符串组装成 a 来减少锁争用,然后将已经组装的字符串发送到std::cout
吗?如:
{
std::stringstream ss;
ss << stringA << " 1 " << 5 << 'C' << std::endl;
std::lock_guard<std::mutex> lock(mutex);
std::cout << ss.str();
}
如果是,是否可以进一步改进?
解决方案
理论上我可以通过在进入互斥体之前将字符串组装成 std::stringstream 来减少锁争用,然后将已经组装的字符串发送到 std::cout 吗?
绝对地。operator<<
必须做一些工作来格式化传入的类型。将字符串组装成 astd::stringstream
意味着您预先完成所有工作,只需将组装好的字符串写出到std::cout
,这意味着您在锁定下花费的时间更少。
但是,请注意,它会按值ss.str()
返回std::string
。这意味着您正在复制关键区域内的字符串。最好直接std::cout << ss.rdbuf()
在里面写下底层字符串std::stringstream
。
除此之外,您还需要尽可能减少输出所花费的时间std::cout
。如果你从不调用任何 C stdio 函数,你应该调用std::ios_base::sync_with_stdio(false)
把它放在一起:
// Near the beginning of your program:
std::ios_base::sync_with_stdio(false);
// ...
{
// Prefer using ostringstream if you never need to read from it
std::ostringstream ss;
// std::endl is never needed. Use '\n' instead. If you want to flush,
// explicitly write `ss << '\n' << std::flush`. For stringstreams, I believe
// it doesn't matter, but it's good to get into the habit of doing this
ss << stringA << " 1 " << 5 << 'C' << '\n';
std::lock_guard<std::mutex> lock(mutex);
std::cout << ss.rdbuf();
}
推荐阅读
- angular - 带有异步 RxJS 调用的 Angular 反应表单自定义验证器
- spring - 如何正确地将 RetryAdvice 添加到 Jms.messageDriverChannelAdapter
- laravel - OctoberCMS (Laravel) 在 Azure windows 主机上缓存“权限问题”
- haskell - 为什么这个 Functor 的类实例不能接受这种结构保持的“fmap”?
- c# - 如何让用户在.Net Core中只喜欢/不喜欢图片一次
- android - 2个Android.mk文件之间的依赖关系
- angular - 从 json 响应创建动态嵌套组件
- sql - 计数 CASE WHEN 的输出
- java - java.lang.IllegalArgumentException:Spring Controller 中的参数类型不匹配
- ubuntu - 在 Ubuntu 中“make install”redis-5.0.5 之后尝试“make uninstall”redis-4.0.10