簡體   English   中英

使用stringstreams加速std :: cout日志記錄

[英]Speed up std::cout logging with stringstreams

我正在嘗試加速一個多線程程序,它打印很多東西到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();
}

如果是,可以進一步改進嗎?

理論上我可以通過在進入互斥鎖之前將字符串組裝成std :: stringstream來減少鎖爭用,然后將已經匯編的字符串發送到std :: cout嗎?

絕對。 operator<<必須做一些工作來格式化傳入的類型。將字符串組裝成std::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();
}

我會完全刪除字符串流,而不是std::string::appendstd::to_string 流往往會拖動很多面向語言環境的東西,並使實現比原始字符串操作更重。 我會這樣做:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM