我和一位同事就lock_guard进行了争论,他认为由于实例化和销毁lock_guard类的成本,lock_guard可能比mutex::lock() / mutex::unlock()慢。
然后我创建了这个简单的测试,令人惊讶的是,使用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++
可以抛出任何异常或将来可能变得更加复杂,你几乎必须使用某种对象来拥有锁。 - François Andrieux