[英]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::append
和std::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.