本来想自己写的,一看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. C++11之函数对象

    目录 1.使用场景 2.函数对象 3.std::bind 4.总结 1.使用场景 在没有C++11的时候,我们通常使用回调函数来完成某些特定的功能,使用回调函数就需要先声明函数指针 示例: typed ...

  2. 给textarea添加行号,textarea使用代码风格的一些思考

    背景 项目有个需求是 在textarea中编辑脚本并显示为代码风格样式,显示行号: textarea显示行号 思路: 1.监听textarea内容变化,执行一个change函数,解析内容里面有多少个换 ...

  3. TF-VAEGAN:添加潜在嵌入(Latent Embedding)的VAEGAN处理零样本学习

    前面介绍了将VAE+GAN解决零样本学习的方法:f-VAEGAN-D2,这里继续讨论引入生成模型处理零样本学习(Zero-shot Learning, ZSL)问题.论文"Latent Em ...

  4. P10114 [LMXOI Round 1] Size 题解

    题目链接:[LMXOI Round 1] Size 挺有意思的诈骗题,其实这类题都喜欢批一个外壳,例如数据范围提示之类的.记得以前遇到的很多诈骗题,有一道 cf 的高分题,问的是区间出现次数的次数 \ ...

  5. 5个.NET开源且强大的快速开发框架(帮助你提高生产效率)

    中台Admin(Admin.Core) 中台Admin(Admin.Core)是前后端分离权限管理系统,前端 UI 基于Vue3开发,后端 Api 基于.NET 8.0开发.支持多租户.接口权限.数据 ...

  6. 【奶奶看了都会】ChatGPT3.5接入企业微信,可连续对话

    1.连续对话效果 小伙伴们,这周ChatGPT放出大招,开放了GPT3.5的API.说简单点,就是提供了和ChatGPT页面对话一样模型的接口.而之前接的ChatGPT接口都是3.0,并不是真正的Ch ...

  7. 小知识:Exadata平台去掉密码输错延迟10分钟登录

    生产环境不评价,若是测试环境实在受不了偶尔一次因为密码输错就要等待10分钟才能登陆的限制. 那测试环境下,如何关闭这个限制呢?很简单: # vi /etc/pam.d/sshd --找到并注释掉下面这 ...

  8. 关于DbgridEh滚动从表一起跟着滚动的分析

    我的实现:

  9. liveness-probe探针和readness-probe

    目录 探针 liveness-probe 存活探针 探针的3种方式 1. exec 2. httpGet 3. tcpSocket readness-probe 就绪探针 1. exec 2. htt ...

  10. NVME(学习笔记_杂谈)

    NVME 协议中一些概念的理解: 1.Namespace :可以将Namespace 理解为一片Logic Block的区域,一个Controller可以支持多个Namespace,每个Namespa ...