Tôi đã tranh cãi với một đồng nghiệp, về lock_guard, và anh ấy đề xuất rằng lock_guard chậm hơn đáng kể so với mutex :: lock () / mutex :: Unlock () do chi phí khởi tạo và hủy liên kết khóa lock_guard.
Sau đó, tôi đã tạo ra thử nghiệm đơn giản này và thật ngạc nhiên, phiên bản có lock_guard nhanh hơn gần hai lần so với phiên bản có 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;
}
Kết quả trên máy của tôi:
Take: 41 ms
Take: 22 ms
Ai đó có thể làm rõ tại sao và làm thế nào điều này có thể được?
std::lock_guard
chậm hơn một chút, trừ khi bạn có thể chứng minh rằng nó quan trọng về hiệu suất, tốc độ tăng sẽ không làm mất hiệu lực các lợi ích khác của việc sử dụng std::lock_guard
(chủ yếu là RAII). Nếu g++
bất cứ thứ gì có thể ném hoặc bất cứ thứ gì có thể thay đổi thành thứ gì đó có khả năng phức tạp hơn trong tương lai, bạn gần như phải sử dụng một số loại đối tượng để sở hữu khóa.