使用stringstreams加快std :: cout日志记录

时间:2018-08-15 22:22:10

标签: c++

我正在尝试加快在std::cout上打印很多内容的多线程程序。大部分打印的东西都是由几个变量(字符串,数字等)拼凑而成的字符串。对std::cout的访问受互斥量保护,以防止来自多个线程的打印输出以下列方式混合在一起:

{
    std::lock_guard<std::mutex> lock(mutex);
    std::cout << stringA << " 1 " << 5  << 'C' << std::endl;
}

测量表明,由于std::cout似乎需要花费一些时间来处理大型而复杂的字符串,因此多个线程花费大量时间等待互斥体。

我的问题是:

从理论上讲,我可以通过在进入互斥锁之前将字符串组装成std::stringstream,然后将已经组装好的字符串发送到std::cout来减少锁争用吗?如:

{
    std::stringstream ss;
    ss << stringA << " 1 " << 5  << 'C' << std::endl;
    std::lock_guard<std::mutex> lock(mutex);
    std::cout << ss.str();
}

如果是,这是否可以进一步改善?

2 个答案:

答案 0 :(得分:4)

  

从理论上讲,我可以通过在进入互斥锁之前将字符串组装到std :: stringstream中,然后将已经组装好的字符串发送到std :: cout来减少锁争用吗?

绝对。 operator<<必须做一些工作来格式化传入的类型。将字符串组装成std::stringstream意味着您要先完成所有工作,而只需要将组装后的字符串写出到{{1} },这意味着您在锁定下花费的时间更少。

但是,请注意std::cout会按值返回ss.str()。这意味着您正在关键区域内复制字符串。最好写std::string并直接在std::cout << ss.rdbuf()内写基础字符串。

除此之外,您将希望尽可能减少输出到std::stringstream所花费的时间。如果您从不调用任何C stdio函数,则可能应该调用std::cout

将其组合在一起:

std::ios_base::sync_with_stdio(false)

答案 1 :(得分:1)

我将完全丢弃字符串流,而赞成std::string::appendstd::to_string。流倾向于拖拽很多面向语言环境的东西,并使实现比原始字符串操作更重。我会这样:

 std::string str;
 str.append(stringA).append(" 1 ").append('C').append('\n');
 std::cout << str;