背景
OSRM backend 代码中有一个timing_util.hpp的头文件,其利用宏以及c++11 chrono 实现了统计代码运行时间的工具。
在工程中统计代码运行时间非常常用,本文介绍OSRM timing_util的实现原理,并用示例来说明。
实现解析
timing_util.hpp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#ifndef TIMING_UTIL_HPP
#define TIMING_UTIL_HPP
#include <chrono>
#include <cstdint>
namespace osrm
{
namespace util
{
// 用TIMER_START 定义一个变量记录开始的时间
#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start
// 用TIMER_STOP 定义一个变量记录结束的时间
#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now()
// TIMER_NSEC 定义start到stop经历了多少纳秒
#define TIMER_NSEC(_X) \
std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count()
// TIMER_USEC 定义start到stop历经多少微秒
#define TIMER_USEC(_X) \
std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count()
// TIMER_MSEC 定义start到stop经历多少毫秒
#define TIMER_MSEC(_X) \
(0.000001 * \
std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count())
// TIMER_SEC 定义start到stop经历多少秒
#define TIMER_SEC(_X) \
(0.000001 * \
std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count())
// TIMER_MIN 定义start到stop经历多少分钟
#define TIMER_MIN(_X) \
std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
}
}
#endif // TIMING_UTIL_HPP
timing_util在定义宏变量时使用 ##,##的作用是把宏参数和相邻的字符进行字符串连接,# 的作用是把宏参数当做一个字符串。以下是关于宏中# 以及## 用法的示例。
1 | /************************************************************************* |
TIMING_UTIL统计运行时间示例
timing_util.cpp1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29/*************************************************************************
> File Name: timing_util.cpp
> Author: ce39906
> Mail: ce39906@163.com
> Created Time: 2018-06-05 17:46:50
************************************************************************/
#include "timing_util.hpp"
#include <iostream>
using namespace osrm::util;
int main()
{
TIMER_START(x);
for (int i = 0; i < 10000; i++)
{
for (int j = 0; j < 10000; j++)
{
int ij = i * j;
}
}
TIMER_STOP(x);
std::cout << "Two Level Loop Cost " << TIMER_NSEC(x) << " ns.\n";
std::cout << "Two Level Loop Cost " << TIMER_USEC(x) << " us.\n";
std::cout << "Two Level Loop Cost " << TIMER_MSEC(x) << " ms.\n";
std::cout << "Two Level Loop Cost " << TIMER_SEC(x) << " s.\n";
std::cout << "Two Level Loop Cost " << TIMER_MIN(x) << " min.\n";
return 0;
}
编译
1 | g++ timing_util.cpp -o timing_util --std=c++11 |
运行1
./timing_util
运行结果如下