Benchmarking de l'horodatage nanoseconde : std::chrono vs clock_gettime(CLOCK_REALTIME)
En C/C++, il existe deux méthodes essentielles d’horodatage avec une résolution nanoseconde :
Méthode A : std::chrono::high_resolution_clock
benchmark_nanosecond_timestamping.cpp
uint64_t getCurrentNanoTimestampCpp() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}Cette méthode nécessite uniquement C++11 et la bibliothèque standard C++. Elle est portable et fonctionne sur toutes les plateformes qui supportent C++11.
Méthode B : clock_gettime(CLOCK_REALTIME)
get_current_nanotime_c.cpp
#include <ctime>
uint64_t getCurrentNanoTimestampC() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec;
}Cette méthode est disponible sur les systèmes conformes à POSIX et n’est pas portable vers Windows.
Benchmarking
Voir ci-dessous pour le code complet pour comparer les deux méthodes.
Résultats
Résultats sur Intel(R) Core(TM) i7-14700, Ubuntu avec le noyau 6.8.1-1018-realtime et g++ -fexpensive-optimizations -O3 -march=native -o benchmark_nanosecond_timestamping benchmark_nanosecond_timestamping.cpp
benchmark_results.txt
C clock_gettime average time per call: 13.603 ns
C++ chrono average time per call: 14.1544 nsEn d’autres termes :
- Les deux méthodes sont extrêmement rapides,
clock_gettimeétant légèrement plus rapide. - Bien que la méthode
std::chronosemble faire des appels de fonction plus complexes, ceux-ci semblent être optimisés par le compilateur. - La différence de performance est négligeable, et les deux méthodes conviennent à l’horodatage haute résolution.
Code complet du benchmark
benchmark_nanosecond_timestamping_full.cpp
#include <iostream>
#include <chrono>
#include <ctime>
uint64_t getCurrentNanoTimestampC() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (uint64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec;
}
uint64_t getCurrentNanoTimestampCpp() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now().time_since_epoch()
).count();
}
void benchmarkFunction(uint64_t (*func)(), const std::string& name, int iterations) {
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
func();
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::nano> duration = end - start;
std::cout << name << " average time per call: "
<< (duration.count() / iterations) << " ns" << std::endl;
}
int main() {
constexpr int iterations = 10000000;
benchmarkFunction(getCurrentNanoTimestampC, "C clock_gettime", iterations);
benchmarkFunction(getCurrentNanoTimestampCpp, "C++ chrono", iterations);
return 0;
}Check out similar posts by category:
C/C++, Performance, Benchmarks
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow