C++利用宏实现统计运行时间工具

背景

OSRM backend 代码中有一个timing_util.hpp的头文件,其利用宏以及c++11 chrono 实现了统计代码运行时间的工具。
在工程中统计代码运行时间非常常用,本文介绍OSRM timing_util的实现原理,并用示例来说明。

实现解析

timing_util.hpp

1
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*************************************************************************
> File Name: test_macro.cpp
> Author: ce39906
> Mail: ce39906@163.com
> Created Time: 2018-06-05 17:38:01
************************************************************************/
#include <iostream>

#define STR(s) #s
#define CONS(a, b) int(a##e##b)

int main()
{
// 输出字符串abc
std::cout << STR(abc) << std::endl;
// 输出2000 (2e3 == 2000)
std::cout << CONS(2, 3) << std::endl;
return 0;
}

TIMING_UTIL统计运行时间示例

timing_util.cpp

1
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

运行结果如下
avatar

Donate
0%