【C语言进阶】使用gettimeofday为你的程序运行时间做统计

news2024/11/29 6:33:32

作者简介

架构师李肯(全网同名),一个专注于嵌入式IoT领域的架构师。有着近10年的嵌入式一线开发经验,深耕IoT领域多年,熟知IoT领域的业务发展,深度掌握IoT领域的相关技术栈,包括但不限于主流RTOS内核的实现及其移植、硬件驱动移植开发、网络通讯协议开发、编译构建原理及其实现、底层汇编及编译原理、编译优化及代码重构、主流IoT云平台的对接、嵌入式IoT系统的架构设计等等。拥有多项IoT领域的发明专利,热衷于技术分享,有多年撰写技术博客的经验积累,连续多月获得RT-Thread官方技术社区原创技术博文优秀奖,荣获CSDN博客专家、CSDN物联网领域优质创作者、2021年度CSDN&RT-Thread技术社区之星、2022年RT-Thread全球技术大会讲师、RT-Thread官方嵌入式开源社区认证专家、RT-Thread 2021年度论坛之星TOP4、华为云云享专家(嵌入式物联网架构设计师)等荣誉。坚信【知识改变命运,技术改变世界】!


【C语言进阶】使用gettimeofday为你的程序运行时间做统计

有时候在编程调试的时候,会遇到个别性能问题需要调试,这时候我们需要比较精确地统计每段代码的耗时情况,这种情况下,你是怎么做的呢?本文介绍一种方法来实现此功能。

文章目录

  • 1 需求背景
  • 2 简要分析
    • 2.1 算法分析
    • 2.2 gettimeofday简介
  • 3 源码实现
    • 3.1 参考代码
    • 3.2 代码简介
    • 3.3 代码测试
  • 4 小小总结
  • 5 更多分享

1 需求背景

在项目编程中,如果遇到调试代码性能的时候,慢慢需要加时戳来观察,找出那些耗时的操作。这种情况大部分需要人工干涉,如果我们需要程序自动帮忙完成耗时分析呢?我们可以怎么做呢?

本文就这个场景问题,提供一种解决方案,欢迎大家参考。

2 简要分析

2.1 算法分析

根据我们的常识,我们知道,要想知道一个操作的耗时,一般的做法就是在操作前取一个时间,然后操作后取一个时间;最后两个时间相减,得到的就是这段操作的耗时。

根据这里方法论,我们可以比较快地实现逻辑代码,但是我们应该用哪个函数取当前时间点呢?

2.2 gettimeofday简介

在Linux C语言编程中,我们很容易会想到gettimeofday这个函数,下面我们将简单介绍一下这个函数。

参考Linux下的man说明,如下:

GETTIMEOFDAY(2) Linux Programmer’s Manual GETTIMEOFDAY(2)

NAME
gettimeofday, settimeofday - get / set time

SYNOPSIS
#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

int settimeofday(const struct timeval *tv, const struct timezone *tz);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

settimeofday():
    Since glibc 2.19:
        _DEFAULT_SOURCE
    Glibc 2.19 and earlier:
        _BSD_SOURCE

DESCRIPTION
The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone.

The tv argument is a struct timeval (as specified in <sys/time.h>):

    struct timeval {
        time_t      tv_sec;     /* seconds */
        suseconds_t tv_usec;    /* microseconds */
    };

and gives the number of seconds and microseconds since the Epoch (see time(2)).

The tz argument is a struct timezone:

    struct timezone {
        int tz_minuteswest;     /* minutes west of Greenwich */
        int tz_dsttime;         /* type of DST correction */
    };

If either tv or tz is NULL, the corresponding structure is not set or returned.  (However, compilation warnings will result if tv is NULL.)

The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.  (See NOTES below.)

Under  Linux,  there are some peculiar "warp clock" semantics associated with the settimeofday() system call if on the very first call (after booting) that has a non-NULL tz argument,
the tv argument is NULL and the tz_minuteswest field is nonzero.  (The tz_dsttime field should be zero for this case.)  In such a case it is assumed that the CMOS clock  is  on  local
time, and that it has to be incremented by this amount to get UTC system time.  No doubt it is a bad idea to use this feature.

RETURN VALUE
gettimeofday() and settimeofday() return 0 for success, or -1 for failure (in which case errno is set appropriately).

从这里我们可以知道,gettimeofday用于获取当前的时间是非常容易的,它会将时间结果存储在这个结构体中:

struct timeval {
time_t tv_sec; /* seconds /
suseconds_t tv_usec; /
microseconds */
};

struct timeval 结构体中有 tv_sec 秒参数 和 tv_usec 微妙参数,非常有利于我们做时间的加减计算。

下面我们就用这个函数来实现下本期的功能。

3 源码实现

3.1 参考代码

本例给出一个参考代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

static int get_cur_time_ms(void)
{
    struct timeval tv;

    gettimeofday(&tv, NULL);  //使用gettimeofday获取当前系统时间

    return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval结构体将时间转换为ms
}

3.2 代码简介

代码的功能逻辑,正如上面 的函数描述所说,正是利用gettimeofday返回的struct timeval结构内的成员变量,通过秒、毫秒、微妙的数量转换,将当前时间转换成毫秒,然后以函数返回值的形式输出。

值得注意的是,虽然gettimeofday在结构体定义上 【号称】有微妙级的精度,但是实际大部分的平台是没法达到这样的精度的,所以我们取其中,转换成毫秒级的精度,这个已经满足我们绝大多数应用场景了。

3.3 代码测试

针对上面的功能代码,写了一段小代码来测试下。

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

static int get_cur_time_ms(void)
{
    struct timeval tv;

    gettimeofday(&tv, NULL);  //使用gettimeofday获取当前系统时间

    return (tv.tv_sec * 1000 + tv.tv_usec / 1000); //利用struct timeval结构体将时间转换为ms
}

static void get_rand_bytes(unsigned char *data, int len)
{
    int a;
    int i;

    srand((unsigned)time(NULL)); //种下随机种子
    for (i = 0; i < len; i++) {
        data[i] = rand() % 255; //取随机数,并保证数在0-255之间
        //printf("%02X ", data[i]);
    }  
}

int main(int argc, const char **argv)
{
    int t1;
    int t2;
    unsigned char data[1024000];

    t1 = get_cur_time_ms();
    get_rand_bytes(data, sizeof(data));
    t2 = get_cur_time_ms();
    printf("random %d bytes, waste time: %dms\n", sizeof(data), t2 - t1); //打印耗时

    return 0;
}

以下测试代码的逻辑还是很简单的,主要就是测试获取 1024000个随机数的耗时情况。

image-20221205132449215

由于我本次测试使用的PC主机,其性能还是不错,所以测试出来的数据,还是耗时比较小的;如果这段代码放在嵌入式平台去运行的话,一个可能data数组的内存会爆,第二个耗时可能会大大增加。

感兴趣的朋友可以拿去一试。

注,本次测试的PC机情况如下:

image-20221205132334585

4 小小总结

  • 面对需求说明,尽快找到核心的功能要点,找到算法逻辑是关键;
  • 明白要做什么,再去选择合适的函数来满足功能逻辑,这是比较好的思路;
  • 考虑到gettimeofday的实际精度问题,牺牲部分不起眼的精度,依然可以满足大部分的需求。

5 更多分享

架构师李肯

架构师李肯全网同名),一个专注于嵌入式IoT领域的架构师。有着近10年的嵌入式一线开发经验,深耕IoT领域多年,熟知IoT领域的业务发展,深度掌握IoT领域的相关技术栈,包括但不限于主流RTOS内核的实现及其移植、硬件驱动移植开发、网络通讯协议开发、编译构建原理及其实现、底层汇编及编译原理、编译优化及代码重构、主流IoT云平台的对接、嵌入式IoT系统的架构设计等等。拥有多项IoT领域的发明专利,热衷于技术分享,有多年撰写技术博客的经验积累,连续多月获得RT-Thread官方技术社区原创技术博文优秀奖,荣获CSDN博客专家、CSDN物联网领域优质创作者、2021年度CSDN&RT-Thread技术社区之星、2022年RT-Thread全球技术大会讲师、RT-Thread官方嵌入式开源社区认证专家、RT-Thread 2021年度论坛之星TOP4、华为云云享专家(嵌入式物联网架构设计师)等荣誉。坚信【知识改变命运,技术改变世界】!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/87948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pcl点云处理

pcl点云处理 1.安装 系统&#xff1a; ubuntu20.04 方法1. 直接命令行方式安装 sudo apt-get install libpcl-devubuntu20.04下默认的pcl版本是1.10. 头文件路径在/usr/include/pcl-1.10/ 方法2.源码编译安装 推荐源码安装&#xff0c;我们安装1.12.1版本&#xff0c;直…

pve制作资源池

pve制作资源池pve制作资源池步骤1.创建资源池2.添加资源池存储成员3.创建用户身份组进行管理4.查看用户角色权限划分单个权限5.创建新角色控制权限6.创建群组权限7.创建测试用户8.模板制作将模板进行迁移&#xff0c;错误&#xff1a;pve无法迁移&#xff1a; cant migrate VM …

kafaka ElasticSearch 集群,解决问题,工作流程及配置

一、作用 性能优化&#xff1a;jvm多线程和I/O&#xff0c;kafkaes 组合的架构&#xff0c;是为了降低es io瓶颈 二、工作流程 如下两图示意&#xff0c; agent&#xff08;指的是filebeat、metricbeat、auditbeat、API服务、logstash&#xff09;收集需要提取的日志文件&…

【linux】之大数据基础平台实施及运维下

一、完全分布式部署介绍 学习目标 能够了解完全分布式部署场景 完全分部式是真正利用多台Linux主机来进行部署Hadoop&#xff0c;对Linux机器集群进行规划&#xff0c;使得Hadoop各个模块分别部署在不同的多台机器上。 二、NameNode HA完全分布式部署 学习目标 能够了解HA完…

计算机网络习题集

文章目录题目答案&#xff1a;题目一&#xff1a;答案一&#xff1a;题目二答案二&#xff1a;题目三&#xff1a;题四&#xff1a;答案四&#xff1a;题目答案&#xff1a; 一、 单项选择题 计算机网络最突出的优点是( D ) A. 精度高 B. 内存容量大 C. 运算速度快 D. 共享资…

【深入浅出SpringCloud原理及实战】「SpringCloud-Alibaba系列」微服务模式搭建系统基础架构实战指南及版本规划踩坑分析

前提介绍 SpringCloud-Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件&#xff0c;方便开发者通过 Spring Cloud编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba&#xff0c;您只需要添加一些注解和少量配…

计算机网络(自顶向下)学习笔记——网络层

第四章—网络层 4.1、概述 转发功能和路由选择功能的区别&#xff1f; 转发涉及在单个的路由中从一条入链路到一条出链路的传送路由选择涉及一个网络的所有路由器&#xff0c;他们经路由选择协议共同交互&#xff0c;决定分组从源到目地结点所采用的的路径 4.1.1、转发和路…

Metal每日分享,调整透明度滤镜效果

本案例的目的是理解如何用Metal实现调整透明度效果滤镜&#xff0c;核心就是改变图像像素的透明度值&#xff1b; Demo HarbethDemo地址 实操代码 // 透明度滤镜 let filter C7Opacity.init(opacity: 0.75)// 方案1: ImageView.image try? BoxxIO(element: originImage, …

java MybatisPlus入门 字段映射 分页查询 逻辑删除 乐观锁

MyBatisPlus&#xff08;简称MP&#xff09;是基于MyBatis框架基础上开发的增强型工具&#xff0c;旨在简化开发、提高效率 入门案例 继承BaseMapper<自己的domain类> 就可以了&#xff0c;自动装配后直接会有各种方法 标准数据层开发 MP分页查询功能 条件查询 NULL值控制…

玩以太坊链上项目的必备技能(单位以及全局变量-Solidity之旅七)

以太币单位&#xff08;Ether&#xff09; 甭管是虚拟货币还是现实中的“稳定币”&#xff0c;他们都有各自的货币单位。当然咯&#xff0c;作为以太坊区块链上交易的虚拟货币以太坊也是有属于自己的那一套货币单位的。 而目前以太币&#xff08;Ether&#xff09;主要分为这…

python批量下载apache文件服务器文件

此脚本用于下载apache文件服务器中制定某个文件夹下所有文件与文件夹。 包含下载单个文件的方法、拼接url递归下载的方法、参数解析。 1 下载文件 功能点&#xff1a; 文件下载 以追加写的方式打开一个新文件&#xff0c;按照块大小写入文件 with open(filepath, wb) as fi…

Kafka实战 - 03 Kafka生产者:将X平台的告警和事件数据接入到S平台

文章目录1. 项目背景2. 依赖和配置3. 生产者配置 KafkaConfiguration4. 同步数据Topic枚举 SyncDataTopicEnum5. 请求体 DataSyncQo6. 同步数据控制层 AppSyncDataController7. 同步数据业务层 XdrDataSyncServiceImpl1. 项目背景 资产可能会遭受各种网络攻击&#xff0c;安全…

[附源码]Python计算机毕业设计SSM基于JAVA语言的宠物寄养管理(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

1,4-丁炔二醇BYD物料中含有大量铜离子、二氧化硅等杂质怎么办?

1,4-丁炔二醇BYD&#xff08;but-2-yne-1,4-diol&#xff09;是一种重要的中间体化工原料&#xff0c;广泛应用于生产丁二醇及其下游产品、维生素B6的主要原料&#xff0c;还可以用于镀镍的增亮剂、防腐抑制剂等领域。 1,4&#xff0d;丁二醇&#xff08;BDO&#xff09;是一种…

[附源码]Python计算机毕业设计SSM基于web的社团管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

免费开源的图片修复工具Lama Cleaner

什么是 Lama Cleaner &#xff1f; Lama Cleaner 是由 SOTA AI 模型提供支持的图像修复工具。可以从图片中移除任何不需要的物体、缺陷和人&#xff0c;或者擦除并替换&#xff08;powered by stable diffusion&#xff09;图片上的任何东西。 看看官方提供的视频&#xff0c;应…

图片怎么转换成PDF格式?这两种方法都可以实现转换

怎么把图片转换成PDF格式呢&#xff1f;大家在日常中也会经常使用到图片&#xff0c;不管是出门游玩还是办公学习&#xff0c;图片都会给我们带来极大的便利。但是一旦图片的数量多了起来&#xff0c;我们又不能删除&#xff0c;那么这些图片的存放就是一个关键的问题&#xff…

[附源码]计算机毕业设计的小说阅读系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

“数据湖存储”冠军杯足球赛开幕,腾讯云存储出征!

“数据湖存储”冠军杯是数据湖领域内的世界级赛事&#xff0c;随着云上“数据湖存储”产品理念的逐步普及&#xff0c;今年的比赛也获得了国内外众多球迷的关注。腾讯云以COS、GooseFS、GooseFSx、元数据加速器、COS加速器等球员组成的球队一路披荆斩棘&#xff0c;成为最闪耀的…

化工集团公司安全风险智能化管控平台

加快数字化发展&#xff0c;大力推进信息化、工业化融合&#xff0c;是国家新时代、新阶段作出的重要决策部署&#xff0c;是化工集团公司打造世界领先企业的必由之路。要充分认识加快数字化发展的重要性紧迫性。要锚定集团公司数字化转型升级的总目标&#xff0c;坚持顶层设计…