本来想自己写的,一看github上面都有就不再重复造轮子了。github上的项目如下:

  • StopWatch 纯标准库实现:使用std::chrono::high_resolution_clock,其实就是std::chrono::steady_clock的别名。
  • StopWatch 类似C#的实现:和C#的StopWatch比较像,在Windows下使用的是QueryPerformanceCounter系统API,其它系统下使用std::chrono::steady_clock

纯标准库实现

第一种纯标准库实现的Stopwatch.hpp内容如下:

// Copyright Ingo Proff 2017.
// https://github.com/CrikeeIP/Stopwatch
// Distributed under the MIT Software License (X11 license).
// (See accompanying file LICENSE) #pragma once #include <vector>
#include <string>
#include <chrono> namespace stopwatch{ class Stopwatch{
public:
enum TimeFormat{ NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS }; Stopwatch(): start_time(), laps({}) {
start();
} void start(){
start_time = std::chrono::high_resolution_clock::now();
laps = {start_time};
} template<TimeFormat fmt = TimeFormat::MILLISECONDS>
std::uint64_t lap(){
const auto t = std::chrono::high_resolution_clock::now();
const auto last_r = laps.back();
laps.push_back( t );
return ticks<fmt>(last_r, t);
} template<TimeFormat fmt = TimeFormat::MILLISECONDS>
std::uint64_t elapsed(){
const auto end_time = std::chrono::high_resolution_clock::now();
return ticks<fmt>(start_time, end_time);
} template<TimeFormat fmt_total = TimeFormat::MILLISECONDS, TimeFormat fmt_lap = fmt_total>
std::pair<std::uint64_t, std::vector<std::uint64_t>> elapsed_laps(){
std::vector<std::uint64_t> lap_times;
lap_times.reserve(laps.size()-1); for( std::size_t idx = 0; idx <= laps.size()-2; idx++){
const auto lap_end = laps[idx+1];
const auto lap_start = laps[idx];
lap_times.push_back( ticks<fmt_lap>(lap_start, lap_end) );
} return { ticks<fmt_total>(start_time, laps.back()), lap_times };
} private:
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_pt;
time_pt start_time;
std::vector<time_pt> laps; template<TimeFormat fmt = TimeFormat::MILLISECONDS>
static std::uint64_t ticks( const time_pt& start_time, const time_pt& end_time){
const auto duration = end_time - start_time;
const std::uint64_t ns_count = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count(); switch(fmt){
case TimeFormat::NANOSECONDS:
{
return ns_count;
}
case TimeFormat::MICROSECONDS:
{
std::uint64_t up = ((ns_count/100)%10 >= 5) ? 1 : 0;
const auto mus_count = (ns_count /1000) + up;
return mus_count;
}
case TimeFormat::MILLISECONDS:
{
std::uint64_t up = ((ns_count/100000)%10 >= 5) ? 1 : 0;
const auto ms_count = (ns_count /1000000) + up;
return ms_count;
}
case TimeFormat::SECONDS:
{
std::uint64_t up = ((ns_count/100000000)%10 >= 5) ? 1 : 0;
const auto s_count = (ns_count /1000000000) + up;
return s_count;
}
}
}
}; constexpr Stopwatch::TimeFormat ns = Stopwatch::TimeFormat::NANOSECONDS;
constexpr Stopwatch::TimeFormat mus = Stopwatch::TimeFormat::MICROSECONDS;
constexpr Stopwatch::TimeFormat ms = Stopwatch::TimeFormat::MILLISECONDS;
constexpr Stopwatch::TimeFormat s = Stopwatch::TimeFormat::SECONDS; constexpr Stopwatch::TimeFormat nanoseconds = Stopwatch::TimeFormat::NANOSECONDS;
constexpr Stopwatch::TimeFormat microseconds = Stopwatch::TimeFormat::MICROSECONDS;
constexpr Stopwatch::TimeFormat milliseconds = Stopwatch::TimeFormat::MILLISECONDS;
constexpr Stopwatch::TimeFormat seconds = Stopwatch::TimeFormat::SECONDS; std::string show_times( const std::vector<std::uint64_t>& times ){
std::string result("{");
for( const auto& t : times ){
result += std::to_string(t) + ",";
}
result.back() = static_cast<char>('}');
return result;
} }

使用示例如下:

//创建一个stopwatch
sw::Stopwatch my_watch;
my_watch.start(); //Do something time-consuming here... //纳秒
std::uint64_t elapsed_ns = my_watch.elapsed<sw::ns>();
//微秒
std::uint64_t elapsed_mus = my_watch.elapsed<sw::mus>();
//毫秒
std::uint64_t elapsed_ms = my_watch.elapsed();
//秒
std::uint64_t elapsed_s = my_watch.elapsed<sw::s>();

类似C#的实现

第二种类似C#的实现,StopWatch.h代码如下:

#ifndef __STOPWATCH_H__
#define __STOPWATCH_H__ #if defined(_MSC_VER) || defined(__MINGW32__) || defined(WIN32)
#include <Windows.h>
#else
#include <chrono>
#endif class StopWatch
{
public:
StopWatch();
~StopWatch(); //开启计时
void Start(); //暂停计时
void Stop(); //重新计时
void ReStart(); //微秒
double Elapsed(); //毫秒
double ElapsedMS(); //秒
double ElapsedSecond(); private:
long long elapsed_;
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(WIN32)
LARGE_INTEGER start_;
LARGE_INTEGER stop_;
LARGE_INTEGER frequency_;
#else
typedef std::chrono::high_resolution_clock Clock;
typedef std::chrono::microseconds MicroSeconds;
std::chrono::steady_clock::time_point start_;
std::chrono::steady_clock::time_point stop_;
#endif }; #endif // __STOPWATCH_H__

StopWatch.cpp代码如下:

#include "StopWatch.h"

#if defined(_MSC_VER) || defined(__MINGW32__) || defined(WIN32)
StopWatch::StopWatch():elapsed_(0)
{
elapsed_ = 0;
start_.QuadPart = 0;
stop_.QuadPart = 0;
QueryPerformanceFrequency(&frequency_);
}
#else
StopWatch::StopWatch():elapsed_(0),start_(MicroSeconds::zero()),stop_(MicroSeconds::zero())
{
}
#endif StopWatch::~StopWatch()
{
} void StopWatch::Start()
{
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(WIN32)
QueryPerformanceCounter(&start_);
#else
start_ = Clock::now();
#endif } void StopWatch::Stop()
{
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(WIN32)
QueryPerformanceCounter(&stop_);
elapsed_ += (stop_.QuadPart - start_.QuadPart) * 1000000 / frequency_.QuadPart;
#else
stop_ = Clock::now();
elapsed_ = std::chrono::duration_cast<MicroSeconds>(stop_ - start_).count();
#endif } void StopWatch::ReStart()
{
elapsed_ = 0;
Start();
} double StopWatch::Elapsed()
{
return static_cast<double>(elapsed_);
} double StopWatch::ElapsedMS()
{
return elapsed_ / 1000.0;
} double StopWatch::ElapsedSecond()
{
return elapsed_ / 1000000.0;
}

使用示例如下(和C#比较像):

StopWatch sw;
sw.Start();
//Do something time-consuming here...
sw.Stop();
std::cout << "运行时间:" << sw.ElapsedMS() << "毫秒" << std::endl;

总结

  • 如果有代码洁癖的话就使用第一种,纯标准库实现、功能全面、使用方法偏向传统C++。
  • 如果不介意使用系统API的话就使用第二种,功能简单、使用方法偏向传统C#。

C++统计代码运行时间的更多相关文章

  1. c#实现统计代码运行时间

    方法一: //实例化一个计时器 Stopwatch watch = new Stopwatch(); //開始计时 watch.Start(); //此处为要计算的执行代码 for (int i = ...

  2. C++统计程序运行时间代码片段

    因为经常需要统计代码的运行时间,所以计时功能就显得很重要, 记录一下现在喜欢用的计时方式,供日后查阅. 1.下面是计时主函数, bool TimeStaticMine(int id,const cha ...

  3. 在 Linux 如何优雅的统计程序运行时间?恕我直言,你运行的可能是假 time

    最近在使用 time 命令时,无意间发现了一些隐藏的小秘密和强大功能,今天分享给大家. time 在 Linux 下是比较常用的命令,可以帮助我们方便的计算程序的运行时间,对比采用不同方案时程序的运行 ...

  4. C#如何测试代码运行时间

    1.System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // 需要测试 ...

  5. VS2010统计代码行数 [转]

    按CTRL+SHIFT+F (Find in files),勾上支持正则表达式,然后输入搜索内容:  ^:b*[^:b#/]+.*$ 以上表达式的统计可做到:#开头 和 /开头 或者 空行 都不计入代 ...

  6. Eclipse统计代码行数

    开发过程中,经常需要统计代码行数,这时可以通过Eclipse的Search功能来实现. 步骤: 1.在Package Explorer中选中需要统计的包: 2.单击菜单Search-->File ...

  7. Google Analytics统计代码GA.JS中文教程

    2010-12-06 11:07:08|  分类: java编程 |  标签:google  analytics  ga  js  代码  |举报|字号 订阅     Google Analytics ...

  8. Visual Studio VS2010统计代码行数(转载)

    本文转自:http://blog.csdn.net/zhouworld16/article/details/9292851 在网上看到别人用的方法: 按CTRL+SHIFT+F (Find in fi ...

  9. 使用console进行 性能测试 和 计算代码运行时间(转载)

    本文转载自: 使用console进行 性能测试 和 计算代码运行时间

  10. 如何给WordPress安装百度统计代码

    1.注册并登录百度统计,点击页面顶部的“网站中心”,然后点击右上角“+ 新增网站”,填写网站域名确定后,点击“复制代码”:2.登录 WordPress 后台,点击左侧导航栏“外观”里的“编辑”,然后点 ...

随机推荐

  1. 3.2 DLL注入:远程APC异步注入

    APC(Asynchronous Procedure Call)异步过程调用是一种Windows操作系统的核心机制,它允许在进程上下文中执行用户定义的函数,而无需创建线程或等待OS执行完成.该机制适用 ...

  2. LyScript 寻找ROP漏洞指令片段

    ROP绕过片段简单科普一下,你可以理解成一个可以关闭系统自身内存保护的一段机器指令,这段代码需要我们自己构造,这就涉及到在对端内存搜寻这样的指令,LyScript插件增强了指令片段的查找功能,但需要我 ...

  3. Python二分法

    二分法 尽管二分搜索通常优于顺序搜索,但当n较小时,排序引起的额外开销可能并不划算.实际上应该始终考虑,为了提高搜索效率,额外排序是否值得.如果排序一次后能够搜索多次,那么排序的开销不值一提.然而,对 ...

  4. centos7安装protobuf|序列化和反序列化工具

    前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...

  5. 转载洛谷:23.08.19 普及模拟1 T1

    Past 题目描述 所有人,都有一段支离破碎的过去. 你有\(n\)段过去的经历,有时顺利,有时不顺,于是你用一个评价值\(a_i\)来描述你的第\(i\)段经历,它们构成了长度为\(n\)的序列\( ...

  6. 【译】.NET 8 网络改进(二)

    原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 修改 HttpClient 日志记录 自定义(甚至简单地关闭)HttpClientFactory 日志记录是长期请求的功能 ...

  7. Argocd学习

    argocd官网文档链接 ArgoCD官网文档 在K8S集群使用argocd命令将集群添加到argcd的cluster列表中 argocd cluster add kubernetes-admin@i ...

  8. 二进制安装Kubernetes(k8s) v1.27.3 IPv4/IPv6双栈 可脱离互联网

    二进制安装Kubernetes(k8s) v1.27.3 IPv4/IPv6双栈 可脱离互联网 https://github.com/cby-chen/Kubernetes 开源不易,帮忙点个star ...

  9. Centos中安装deb报错

    centos7中安装deb包   概要:deb包和rpm包区别:deb后缀的软件包是for Debian系的(包括Ubuntu),不是给centos安装的:rpm后缀的软件包才是for Redhat系 ...

  10. NVME学习笔记六—Controller Architecture

    Controller架构   NVMe over Fabrics使用与NVMe基础规格说明书中定义相同的controller架构.这包括主机和controller之间使用SQ提交队列和CQ完成队列来执 ...