Estaba discutiendo con un colega, sobre lock_guard, y él propuso que lock_guard es probablemente más lento que mutex :: lock () / mutex :: unlock () debido al costo de instanciar y unificar la clase lock_guard.
Luego creé esta prueba simple y, sorprendentemente, la versión con lock_guard es casi dos veces más rápida que la versión con 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;
}
Los resultados en mi máquina:
Take: 41 ms
Take: 22 ms
¿Alguien puede aclarar por qué y cómo puede ser esto?
std::lock_guard
fue un poco más lento, a menos que pueda probar que es importante en términos de rendimiento, esa ganancia de velocidad no invalidará los otros beneficios del uso std::lock_guard
(principalmente RAII). Si g++
hay algo que puede arrojar o algo que podría cambiar en algo potencialmente más complicado en el futuro, casi tiene que usar algún tipo de objeto para poseer la cerradura.