Я спорил с коллегой о lock_guard, и он предположил, что lock_guard, вероятно, медленнее, чем mutex :: lock () / mutex :: unlock () из-за стоимости создания и удаления класса lock_guard.
Затем я создал этот простой тест, и, что удивительно, версия с 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++
есть что-то, что может бросить или что-то, что может превратиться в нечто потенциально более сложное в будущем, вы почти должны использовать какой-то объект для владения блокировкой.Ответы:
Сборка релиза дает одинаковый результат для обеих версий.
В
DEBUG
сборки показывает ~ 33% больше времени дляfunc2
; Разница я вижу в разборке, котораяfunc2
использует__security_cookie
и вызывает@_RTC_CheckStackVars@8
.Вы рассчитываете DEBUG?
РЕДАКТИРОВАТЬ: Кроме того, глядя на
RELEASE
разборки, я заметил, чтоmutex
методы были сохранены в двух реестрах:и называется одинаково от обоих
func1
иfunc2
:источник