Ich habe mit einem Kollegen über lock_guard gestritten, und er schlug vor, dass lock_guard aufgrund der Kosten für die Instanziierung und Unistantiierung der Klasse lock_guard wahrscheinlich langsamer als mutex :: lock () / mutex :: refresh () ist.
Dann habe ich diesen einfachen Test erstellt und überraschenderweise ist die Version mit lock_guard fast zweimal schneller als die Version mit mutex :: lock () / mutex :: entsperren ()
#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;
}
Die Ergebnisse auf meiner Maschine:
Take: 41 ms
Take: 22 ms
Kann jemand klären, warum und wie das sein kann?
std::lock_guard
es etwas langsamer war, wird dieser Geschwindigkeitsgewinn die anderen Vorteile der Verwendungstd::lock_guard
(hauptsächlich RAII) nicht ungültig machen, es sei denn, Sie können nachweisen, dass es auf die Leistung ankommt . Wenng++
ist alles , was werfen oder etwas kann , die in etwas ändern könnten möglicherweise komplizierte mehr in der Zukunft , die Sie fast haben , um irgendeine Art von Objekt zu verwenden , um das Schloss zu besitzen.Antworten:
Der Release-Build führt für beide Versionen zum gleichen Ergebnis.
Der
DEBUG
Build zeigt ~ 33% längere Zeit fürfunc2
; Der Unterschied, den ich in der Demontage sehe, diefunc2
verwendet__security_cookie
und aufruft@_RTC_CheckStackVars@8
.Planen Sie DEBUG?
BEARBEITEN: Außerdem habe
RELEASE
ich bei der Demontage festgestellt, dassmutex
Methoden in zwei Registern gespeichert wurden:und nannte den gleichen Weg von beiden
func1
undfunc2
:quelle