ฉันโต้เถียงกับเพื่อนร่วมงานเกี่ยวกับ lock_guard และเขาเสนอว่า lock_guard นั้นน่าจะช้ากว่า mutex :: lock () / mutex :: unlock () เนื่องจากราคาของ instantiate และทำให้ชั้น lock_guard ลดลง
จากนั้นฉันก็สร้างการทดสอบอย่างง่ายและแปลกใจรุ่นที่มี lock_guard นั้นเร็วกว่ารุ่นที่มี mutex :: lock () / mutex :: unlock () เกือบสองเท่า
#include <iostream>
#include <mutex>
#include <chrono>
std::mutex m;
int g = 0;
void func1()
{
m.lock();
g++;
m.unlock();
}
void func2()
{
std::lock_guard<std::mutex> lock(m);
g++;
}
int main()
{
auto t = std::chrono::system_clock::now();
for (int i = 0; i < 1000000; i++)
{
func1();
}
std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;
t = std::chrono::system_clock::now();
for (int i = 0; i < 1000000; i++)
{
func2();
}
std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;
return 0;
}
ผลลัพธ์ในเครื่องของฉัน:
Take: 41 ms
Take: 22 ms
บางคนสามารถอธิบายได้ว่าเหตุใดจึงเป็นเช่นนี้
std::lock_guard
ช้าลงเล็กน้อยเว้นแต่คุณจะสามารถพิสูจน์ได้ว่ามันสำคัญในแง่ของประสิทธิภาพการเพิ่มความเร็วนั้นจะไม่ทำให้ผลประโยชน์อื่น ๆ ของการใช้std::lock_guard
(ส่วนใหญ่ RAII) เป็นโมฆะ หากg++
เป็นสิ่งที่สามารถโยนหรืออะไรก็ตามที่อาจเปลี่ยนเป็นสิ่งที่อาจซับซ้อนกว่าในอนาคตคุณเกือบจะต้องใช้วัตถุบางอย่างในการเป็นเจ้าของล็อค