C++开发基础之简单的计时器也有适配场景
一、前言
计时器的开发通常涉及到计算时间间隔的方法和计算时间的方式。一般计时器的开发步骤:
-
获取起始时间点:在开始计时时,记录当前的时间戳作为起始时间点。
-
获取结束时间点:在结束计时时,记录当前的时间戳作为结束时间点。
-
计算时间间隔:通过起始时间点和结束时间点的差值,计算出经过的时间间隔。
-
显示计时结果:将计算得到的时间间隔转换成合适的时间单位(如毫秒、秒等),并展示给用户。
二、计时器的适配场景
下面是对比各种方法实现计时器功能的优劣势、适用场景、精度、易用性和平台兼容性的表格:
| 方法 | 优势 | 劣势 | 适用场景 | 精度 | 易用性 | 平台兼容性 |
|---|---|---|---|---|---|---|
<chrono> | 高精度、跨平台 | 需要 C++11 及以上标准支持 | 跨平台应用、需要高精度计时的场景 | 高 | 中 | 良好 |
| 标准库函数 | 简单易用 | 精度可能不够高 | 简单计时需求、不需要太高精度的场景 | 低 - 中 | 高 | 良好 |
| 系统特定函数 | 高精度、系统调用简单 | 可移植性差 | 特定平台上需要更高精度的计时需求 | 高 | 中 | 差 |
| 第三方库 | 功能丰富、可扩展性强 | 引入外部依赖 | 复杂计时需求、需要定制化计时功能的场景 | 高 | 高 | 良好 |
| 硬件计时器 | 高精度、硬件支持 | 硬件依赖性强 | 对计时精度要求极高的场景 | 非常高 | 中 | 依赖硬件 |
三、基于标准库实现
3.1 使用clock函数
使用 clock() 函数实现计时器功能。
- 记录开始时间:在需要开始计时的地方调用
clock()函数,将其返回值保存为开始时间。 - 记录结束时间:在需要结束计时的地方再次调用
clock()函数,将其返回值保存为结束时间。 - 计算时间间隔:将结束时间减去开始时间,然后除以
CLOCKS_PER_SEC来获取经过的时间(以秒为单位)。
#include <iostream>
#include <ctime>int main() {clock_t start, end;double cpu_time_used;start = clock(); // 记录开始时间// 进行需要计时的操作for (int i = 0; i < 1000000; ++i) {// do something}end = clock(); // 记录结束时间cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; // 计算时间间隔std::cout << "CPU time used: " << cpu_time_used << " seconds" << std::endl;return 0;
}
在这个示例中,首先记录了开始时间和结束时间,然后计算了经过的时间间隔。
请注意,由于 clock() 函数返回的是 CPU 时钟周期数,所以需要将其转换为秒数才能得到实际的时间间隔。
3.2 使用time函数
使用 time() 函数实现计时器相对简单,但其精度可能不足以满足高精度计时的需求。
#include <iostream>
#include <ctime>int main() {time_t start, end;double time_used;start = time(NULL); // 记录开始时间// 进行需要计时的操作for (int i = 0; i < 1000000; ++i) {// do something}end = time(NULL); // 记录结束时间time_used = difftime(end, start); // 计算时间间隔std::cout << "Time used: " << time_used << " seconds" << std::endl;return 0;
}
在这个示例中,我们使用 time() 函数获取当前时间的秒数作为开始时间和结束时间,并通过 difftime() 函数计算时间间隔。
请注意,time() 函数返回的时间精度通常是秒级别,因此不适合需要高精度计时的场景。如果需要更高精度的计时功能,建议使用其他方法,如 <chrono> 头文件中的函数。
四、基于chrono库实现
使用<chrono>头文件中的功能来实现计时功能:
#include <iostream>
#include <chrono>class Timer {
public:void start() {startTime = std::chrono::high_resolution_clock::now();}void stop() {endTime = std::chrono::high_resolution_clock::now();}void displayDuration(const std::string& message) {auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);std::cout << message << ": " << duration.count() << " ms" << std::endl;}
private:std::chrono::time_point<std::chrono::high_resolution_clock> startTime, endTime;
};
int main() {Timer timer;timer.start();// 模拟一些操作for (int i = 0; i < 1000000; ++i) {// do something}timer.stop();timer.displayDuration("Elapsed time");return 0;
}
在这个示例中,Timer类封装了计时器的功能。start()方法开始计时,stop()方法停止计时,displayDuration()方法用于显示经过的时间。
在main()函数中,创建一个Timer对象,调用start()开始计时,在模拟的操作后调用stop()停止计时,并调用displayDuration()方法显示经过的时间。
五、基于系统特定函数
5.1 QueryPerformanceCounter
可以使用Windows系统提供的QueryPerformanceCounter()函数来实现简单计时器功能:
#include <iostream>
#include <Windows.h>class Timer {
public:void start() {QueryPerformanceFrequency(&frequency);QueryPerformanceCounter(&startCounter);}void stop() {QueryPerformanceCounter(&endCounter);}void displayDuration(const std::string& message) {LARGE_INTEGER elapsedTime;elapsedTime.QuadPart = endCounter.QuadPart - startCounter.QuadPart;double duration = static_cast<double>(elapsedTime.QuadPart) / frequency.QuadPart;std::cout << message << ": " << duration << " seconds" << std::endl;}private:LARGE_INTEGER frequency;LARGE_INTEGER startCounter, endCounter;
};int main() {Timer timer;timer.start();// 模拟一些操作for (int i = 0; i < 1000000; ++i) {// do something}timer.stop();timer.displayDuration("Elapsed time");return 0;
}
在这个示例中,Timer类使用QueryPerformanceCounter()函数来获取高精度的计时。start()方法开始计时,stop()方法停止计时,displayDuration()方法用于显示经过的时间。
在main()函数中,创建一个Timer对象,调用start()开始计时,在模拟的操作后调用stop()停止计时,并调用displayDuration()方法显示经过的时间。
5.2 GetTickCount64
GetTickCount64函数是Windows API中用于获取系统启动后经过的毫秒数的函数,它可以用来实现简单的计时器功能。
#include <iostream>
#include <Windows.h>class Timer {
public:void start() {startTime = GetTickCount64();}void stop() {endTime = GetTickCount64();}void displayDuration(const std::string& message) {DWORD duration = endTime - startTime;std::cout << message << ": " << duration << " ms" << std::endl;}private:ULONGLONG startTime, endTime;
};int main() {Timer timer;timer.start();// 模拟一些操作for (int i = 0; i < 1000000; ++i) {// do something}timer.stop();timer.displayDuration("Elapsed time");return 0;
}
在这个示例中,Timer类使用GetTickCount64函数来获取系统启动后的毫秒数。start()方法开始计时,stop()方法停止计时,displayDuration()方法用于显示经过的时间。
在main()函数中,创建一个Timer对象,调用start()开始计时,在模拟的操作后调用stop()停止计时,并调用displayDuration()方法显示经过的时间。
六、基于第三方库实现
使用C++中的高精度计时器库ChronoLib来实现计时器功能:
#include <iostream>
#include "ChronoLib.h"int main() {Chrono::high_resolution_timer timer;double elapsed_time = 0.0;// 计时开始timer.start();// 执行需要计时的操作// ...// 计时结束elapsed_time = timer.elapsed();// 输出计时结果std::cout << "Elapsed Time: " << elapsed_time << " seconds" << std::endl;return 0;
}
在这个示例中,我们使用ChronoLib库中的high_resolution_timer类来实现高精度计时器功能。我们创建了一个计时器对象timer和一个变量elapsed_time来保存计时结果。在需要计时的操作执行前,我们通过start函数开始计时。在需要计时的操作执行完成后,我们使用elapsed函数来获取计时结果,并将结果保存到elapsed_time变量中。最后,我们输出计时结果。
七、基于硬件计时器模块实现
硬件计时器通常指的是计算机或嵌入式系统中的专用计时器硬件模块,这些模块通常由硬件设计师设计并集成到处理器或主板中。硬件计时器具有高精度、稳定性和可靠性的特点,通常用于需要精确时间测量和控制的应用场景。
八、总结
每种方法都有其独特的优势和劣势,具体选择取决于项目需求、平台要求和精度要求。
相关文章:
C++开发基础之简单的计时器也有适配场景
一、前言 计时器的开发通常涉及到计算时间间隔的方法和计算时间的方式。一般计时器的开发步骤: 获取起始时间点:在开始计时时,记录当前的时间戳作为起始时间点。 获取结束时间点:在结束计时时,记录当前的时间戳作为结…...
数电学习笔记——逻辑函数及其描述方法
目录 一、逻辑函数 二、逻辑函数的描述方法 1、逻辑真值表 2、逻辑函数式 3、逻辑图 4、波形图 三、逻辑函数的两种标准形式 1、最小项与最大项 最小项 最小项的性质 最大项 最大项的性质 2、最大项与最小项的关系 3、逻辑函数的最小项之和形式 4、逻辑函数的最…...
2024年护眼台灯哪家品牌好?五款优质品牌专业推荐
护眼台灯几乎是每个孩子书桌上都会有的灯具,但还是有不少家长觉得是“智商税”。其实护眼台灯好处非常多,列如能够提供舒适的照明,缓解用眼疲劳,预防近视等等。所以今天准备了一期护眼台灯测评,并附上护眼台灯的榜单&a…...
搜索iconfont或者阿里图标就可以得到免费的图标
你在搜索过程中就会出现一些无耻,不要脸的网站,比如说下面这个 这个才是阿里图标 看它的网址 都是免费的...
android实战视频教程,细数Android开发者的艰辛历程
缘起 随着互联网企业的不断发展,产品项目中的模块越来越多,用户体验要求也越来越高,想实现小步快跑、快速迭代的目的越来越难,还有应用之间的互相调用等等问题,插件化技术应用而生。如果没有插件化技术,美…...
nav2_gps_waypoint_follower_demo 不能在ros2 humble中直接使用的解决方法
GIT上的nav2_gps_waypoint_follower_demo是基于ros-iron编写的,其中followGpsWaypoints(wps) service只能在Iron上使用。 解决方法: 第一步:将interactive_waypoint_follower.py修改为如下代码: import rclpy from rclpy.node …...
华为OD机试 - 螺旋数字矩阵
1 题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法: 给出数字个数 n (0 < n ≤ 999)和行数 m(0 < m ≤ 999),从左上角的 1 开始&…...
Vue响应式内容丢失处理
对数组和对象进行不当的修改会使Vue的对象丢失响应式,这时可以直接console.log丢失的对象,看是否有getter和setter 对于数组和对象,只有使用 Vue 提供的一些方法(如 push()、pop()、splice()、set() 等)进行修改才会触…...
Linux安装Rabbitmq
说明:本文章主要是rabbitmq在Linux系统上的安装,文章中包含了rabbitmq的下载及依赖下载 1.版本选取,这里的选取主要是版本的兼容问题 去这个网址查看mq和erlang版本兼容:RabbitMQ Erlang Version Requirements | RabbitMQ 2.相…...
在nginx 服务器部署vue项目
以人人快速开发的开源项目:renren-fast-vue 为例 注:这里开始认为各位都会使用nginx 打包vue项目 npm run build 测试打包的项目是否可以运行 serve dist 可以正常运行 编译报错请移步到:renren-fast-vue1.2.2 项目编译报错: build g…...
制作一个简单的HTML个人网页
制作一个简单的HTML个人网页 1.1 硬件1.1.1 一台电脑1.1.2 配置要求 1.2 系统1.3 软件 二、制作一个简单的HTML个人网页1.创建一个HTML网页1.1 新建文本文档1.2 另存文本文档1.3 命名为index.html 2.编写HTML代码2.1 打开HTML2.2 复制HTML代码2.3 粘贴HTML代码2.4 保存HTML 3.预…...
HM2019创建载荷工况
该案例中将介绍载荷、工况、约束的创建 步骤一:首先创建两个载荷集(Load Collector)用来存放载荷和约束 步骤二:在Analysis面板下创建约束(Analysis→constraints) 注意:Load type选择SPC表示统计过程控制(Statistical Process Control) 步…...
Effective C++ 学习笔记 条款14 在资源管理类中小心copying行为
条款13导入这样的观念:“资源取得时机便是初始化时机”(Resource Acquisition Is Initialization,RAII),并以此作为“资源管理类”的脊柱,也描述了auto_ptr和tr1::shared_ptr如何将这个观念表现在heap-base…...
c++数据结构算法复习基础-- 3 --线性表-单向链表-笔试面试常见问题
1、单链表逆序 思路图 代码实现 //著: 链表结构里记得加 friend void ReverseLink(Clink& link); void ReverseLink(Clink& link) {Node* p link.head_->next_;while( p nullptr){return;}Node* q p->next_;link.head_->next_ nullptr;while(p ! nullpt…...
【踩坑专栏】追根溯源,从Linux磁盘爆满排查故障:mycat2与navicat不兼容导致日志暴增
昨天遇到了一个比较奇怪的问题,就是在挂起虚拟机的时候,虚拟机提示我XX脚本正在运行,很奇怪,我没有运行脚本,为什么会提示我这个呢。今天恢复虚拟机,也提示了一下脚本的问题,而且发现Linux明显异…...
DolphinScheduler——奇富科技的调度实践
目录 一、技术架构 二、业务挑战 2.1 调度任务量大 2.2 运维复杂 2.3 SLA要求高 三、调度优化实践 3.1 重复调度 3.2 漏调度 3.3 Worker服务卡死 3.4 任务重复运行 四、服务监控 4.1 方法耗时监控 4.2 任务调度链路监控 五、用户收益 原文大佬的这篇调度系统案例…...
2024年最全洗地机选购攻略盘点丨希亦、小米、云鲸、海尔洗地机哪款值得入手?
在现代家居清洁中,洗地机是不可或缺的得力助手,它融合了吸尘、拖地等多种功能。面对市场上琳琅满目的洗地机品牌和型号,选择一个可靠的品牌至关重要。优质的品牌能够提供高品质的产品,使您的清洁工作更加轻松高效。本文将向您推荐…...
HTML笔记3
21,label标签 <label for"...">...</label> <label>...</label> <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content&qu…...
利用Python副业赚钱,看完这篇你就懂了!
Python都可以做哪些副业? 1、兼职处理数据Excel整理数据功能虽然很强大,但在Python面前,曾经统治职场的它也的败下阵来。因为Python在搜集数据整理分析数据的过程中更加便捷,通过几行代码还可以实现自动化操作。 如果你学会Pyth…...
FP16(半精度浮点数)、FP32(单精度浮点数)和INT8
在深度学习和计算机视觉领域中,FP16(半精度浮点数)、FP32(单精度浮点数)和INT8(8 位整数)是常见的数据类型或精度表示方式。它们在不同的场景下有各自的优势和用途。 FP16(半精度浮…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
