Kłóciłem się z kolegą na temat lock_guard, a on zaproponował, że lock_guard jest prawdopodobnie wolniejszy niż mutex :: lock () / mutex :: unlock () ze względu na koszt utworzenia i ujednolicenia klasy lock_guard.
Potem stworzyłem ten prosty test i, co zaskakujące, wersja z lock_guard jest prawie dwa razy szybsza niż wersja z 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;
}
Wyniki na mojej maszynie:
Take: 41 ms
Take: 22 ms
Czy ktoś może wyjaśnić, dlaczego i jak to może być?
std::lock_guard
był nieco wolniejszy, chyba że możesz udowodnić, że ma on znaczenie pod względem wydajności, to wzrost prędkości nie unieważnia innych korzyści wynikających z używania std::lock_guard
(głównie RAII). Jeśli g++
jest coś, co może rzucić lub coś, co może zmienić się w coś potencjalnie bardziej skomplikowanego w przyszłości, prawie musisz użyć jakiegoś obiektu do posiadania zamka.