ในหนังสือ Scott Meyers ฉันพบตัวอย่างของการแสดงออกแลมบ์ดาสากลทั่วไปที่สามารถใช้ในการวัดเวลาการทำงานของฟังก์ชัน (C ++ 14)
auto timeFuncInvocation =
[](auto&& func, auto&&... params) {
// get time before function invocation
const auto& start = std::chrono::high_resolution_clock::now();
// function invocation using perfect forwarding
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
// get time after function invocation
const auto& stop = std::chrono::high_resolution_clock::now();
return stop - start;
};
ปัญหาคือคุณวัดการดำเนินการเพียงครั้งเดียวเพื่อให้ผลลัพธ์ที่แตกต่างกันมาก เพื่อให้ได้ผลลัพธ์ที่เชื่อถือได้คุณควรวัดจำนวนการดำเนินการเป็นจำนวนมาก จากการบรรยายของ Andrei Alexandrescu ที่รหัส :: dive 2015 conference - การเขียน Fast Code I:
เวลาที่วัดได้: tm = t + tq + tn + ถึง
ที่อยู่:
tm - วัดเวลา (สังเกต)
t - เวลาที่สนใจจริง
tq - เวลาที่เพิ่มขึ้นโดยเสียงรบกวนควอนไทซ์
tn - time ถูกเพิ่มเข้ามาด้วยแหล่งกำเนิดเสียงที่หลากหลาย
ถึง - เหนือเวลา (การวัดการวนลูปการเรียกฟังก์ชัน)
ตามที่เขาพูดไว้ในการบรรยายคุณควรใช้เวลาอย่างน้อยที่สุดในการดำเนินการตามผลของคุณ ฉันขอแนะนำให้คุณดูการบรรยายที่เขาอธิบายว่าทำไม
นอกจากนี้ยังมีห้องสมุดที่ดีมากจาก google - https://github.com/google/benchmark https://github.com/google/benchmarkห้องสมุดนี้ใช้งานง่ายและทรงพลัง คุณสามารถชำระเงินการบรรยายของ Chandler Carruth บน youtube ซึ่งเขาใช้ห้องสมุดนี้ในทางปฏิบัติ ตัวอย่างเช่น CppCon 2017: Chandler Carruth“ กำลังไปได้เร็วขึ้น”;
ตัวอย่างการใช้งาน:
#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation =
[](auto&& func, auto&&... params) {
// get time before function invocation
const auto& start = high_resolution_clock::now();
// function invocation using perfect forwarding
for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
}
// get time after function invocation
const auto& stop = high_resolution_clock::now();
return (stop - start)/100000/*largeNumber*/;
};
void f(std::vector<int>& vec) {
vec.push_back(1);
}
void f2(std::vector<int>& vec) {
vec.emplace_back(1);
}
int main()
{
std::vector<int> vec;
std::vector<int> vec2;
std::cout << timeFuncInvocation(f, vec).count() << std::endl;
std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
std::vector<int> vec3;
vec3.reserve(100000);
std::vector<int> vec4;
vec4.reserve(100000);
std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
return 0;
}
แก้ไข: แน่นอนคุณต้องจำไว้ว่าคอมไพเลอร์ของคุณสามารถเพิ่มประสิทธิภาพบางอย่างออกมาหรือไม่ เครื่องมืออย่าง perf อาจมีประโยชน์ในกรณีเช่นนี้
clock_gettime
.. GCC กำหนดนาฬิกาอื่น ๆ เช่น:typedef system_clock steady_clock; typedef system_clock high_resolution_clock;
บน Windows,QueryPerformanceCounter
การใช้งาน