Eu estava discutindo com um colega sobre o lock_guard, e ele propôs que o lock_guard é provavelmente mais lento que o mutex :: lock () / mutex :: unlock () devido ao custo de instanciar e desestabilizar a classe lock_guard.
Então criei esse teste simples e, surpreendentemente, a versão com lock_guard é quase duas vezes mais rápida que a versão com 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;
}
Os resultados na minha máquina:
Take: 41 ms
Take: 22 ms
Alguém pode esclarecer por que e como isso pode ser?
std::lock_guard
sido um pouco mais lento, a menos que você possa provar que é importante em termos de desempenho, esse ganho de velocidade não invalidará os outros benefícios do uso std::lock_guard
(principalmente RAII). Se g++
houver algo que possa ser lançado ou algo que possa se transformar em algo potencialmente mais complicado no futuro, você quase precisará usar algum tipo de objeto para possuir o bloqueio.