1.问:知道程序运行时间我们可以做什么?

在《C++应用程序性能优化》一书中,如果大家读过相信大家一定对性能优化这一块非常上心,文中总是对优化前后的时间对比非常直观给我们一个感受。

那么我们如何利用C语言提供的库函数获取一个应用程序的各阶段的运行效率,通过数据分析出该程序的瓶颈并且做出相应的优化。

本文给大家讲解的clock()函数。

2.我们首先看一看C/C++标准文档对于clock()函数的讲解

3.函数原型 clock_t clock (void);

函数返回值 clock()返回从"开启这个程序进程"到"程序中调用clock()函数"时之间的CPU时钟计时单元(clock tick)数

Returns the processor time consumed by the program.
返回程序所消耗的处理器时间

4.两个重要的概念需要理解一下

epoch:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。
通过时钟作为参考的划时代的系统有所不同,但它是关系到执行程序(通常它的发射)。要计算一个程序的实际处理时间,由时钟返回的值应比由以前调用同一个函数返回一个值。
clock tick:时钟计时单元,一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。

5.clock函数

The value returned is expressed in clock ticks, which are units of time of a constant but system-specific length (with a relation of CLOCKS_PER_SEC clock ticks per second).
返回的值是以时钟计时单元为单位表示,这是一个恒定的但系统特定长度的时间单位(CLOCKS_PER_SEC表示每秒多少时钟计时单元)。
The epoch used as reference by clock varies between systems, but it is related to the program execution (generally its launch). To calculate the actual processing time of a program, the value returned by clock shall be compared to a value returned by a previous call to the same function.

时间点所参考的时钟的在不同系统间,它是关系到程序执行(通常它的启动)。要计算一个程序的实际处理器占用时间,由时钟返回的值应与以前调用同一个函数返回一个值相比。

时间点

Parameters

参数

none
没有

Return Value

返回值

The number of clock ticks elapsed since an epoch related to the particular program execution.

On failure, the function returns a value of -1.
如果失败,函数返回值是-1

一句话这个函数的作用就是:

启动这个程序到程序中调用clock()函数时之间的CPU时钟计时单元(clock tick)的计数。

举一个例子,调用clock的地方就像是我们在体育赛场上掐秒表的动作

100m开跑计时员开始计时,第一个到达终点掐一下显示的时间是9.502s 第二个是9.559s

9.502s和9.559s都是从开始赛跑到终点的计时。这就好比我们的程序开始启动了,我们在一些容易造成性能瓶颈的地方前掐秒表----调用clock()函数一下,完了再掐一下秒表通过计算两次掐表的间隔来评估瓶颈的严重程度。

6.讲讲clock_t
clock_t is a type defined in <ctime> as an alias of a fundamental arithmetic type.

clock_t是一个定义在ctime头文件中的类型 作为一个基本数据类型的别名。

在C语言中clock_t定义的头文件就是time.h

我们打开自己所在开发环境中的time.h 搜索一下clock_t便可以找到了

如下显示

从上如我们可以知道所谓的clock_t其实就是一个long型

7.讲讲CLOCKS_PER_SEC

前面我知道CLOCKS_PER_SEC是某一个特定的值

进入time.h和查看clock_t的方法一样找到CLOCKS_PER_SEC

显示如下

可以看见CLOCKS_PER_SEC是一个宏 意味着在所有出现CLOCKS_PER_SEC的地方在编译的时候就会被替换成1000这个数值。

8. 小试牛刀

现在我们就试验一下 我通过编写3个函数testinit() testwork() testend()

来模拟程序运行的一些模块的运行时间

  1. #include <stdio.h> /* printf */
  2. #include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
  3. #include <math.h> /* sqrt */
  4.  
  5. int testinit (int n)
  6. {
  7. int num = n * n;
  8. while(num)
  9. {
  10. --num;
  11. }
  12. return 0;
  13. }
  14. int testwork (int n)
  15. {
  16. printf ("Begin Calculating...\n");
  17. int i,j;
  18. int freq=n-1;
  19. for (i=2; i<=n; ++i)
  20. for (j=sqrt(i);j>1;--j)
  21. if (i%j==0)
  22. {
  23. --freq;
  24. break;
  25. }
  26. return freq;
  27. }
  28. int testend (int n)
  29. {
  30. int num = n * n;
  31. while(num)
  32. {
  33. --num;
  34. }
  35. return 0;
  36. }
  37. int main ()
  38. {
  39. clock_t t;
  40. int f;
  41. //测试第一阶段 初始化
  42. printf ("Begin clock...\n");
  43. t = clock();//第一个clock() t表示从程序启动到现在这个时刻的时间
  44. testinit(1500);
  45. t = clock() - t;//第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
  46. printf ("It took %d clicks (%f seconds) to call testinit().\n",t,((float)t)/CLOCKS_PER_SEC);
  47.  
  48. //测试第二阶段 工作
  49. //第一个clock() t表示从程序启动到现在这个时刻的时间
  50. t = clock();
  51. f = testwork(99999);
  52. //第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
  53. t = clock() - t;
  54. printf ("It took %d clicks (%f seconds)to call testwork().\n",t,((float)t)/CLOCKS_PER_SEC);
  55. printf ("The number of primes lower than 100,000 is: %d\n",f);
  56.  
  57. //测试第三阶段
  58.  
  59. //第一个clock() t表示从程序启动到现在这个时刻的时间
  60. t = clock(); testend(1255);
  61. //第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
  62. t = clock() - t;
  63. printf ("It took %d clicks (%f seconds)to call testend().\n",t,((float)t)/CLOCKS_PER_SEC);
  64. return 0;
  65. }
Output:

通过比对数据我们分析出 testwork()函数耗时较大,很可能就是项目中的瓶颈。

9.下面我们看看这个程序在各个平台的Unix/Linux运行如何呢?

在RHEL7上

在RHEL6上

在Solaris上

在MAC上

Unix/Linux环境C编程入门教程(22) C/C++如何获取程序的运行时间的更多相关文章

  1. Unix/Linux环境C编程新手教程(22) C/C++怎样获取程序的执行时间

    1.问:知道程序执行时间我们能够做什么? 在<C++应用程序性能优化>一书中,假设大家读过相信大家一定对性能优化这一块很上心,文中总是对优化前后的时间对照很直观给我们一个感受. 那么我们怎 ...

  2. Unix/Linux环境C编程入门教程(32) 环境变量那些事儿

    1. getenv() putenv()setenv()函数介绍 getenv(取得环境变量内容) 相关函数 putenv,setenv,unsetenv 表头文件 #include<stdli ...

  3. Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 本文就带大家来安装Solaris 11 64位并且配置好C/C++开发环境 本文所 ...

  4. Unix/Linux环境C编程入门教程(19)Red Hat Entetprise Linux 7.0环境搭建

    位架构,包括英特尔X-86_64.Power和s390.动态定时能力将降低内核内部中断数量,Open vSwitch 2.0功能可调节虚拟机之间的流量.RHEL 7中默认的文件系统是XFS,包含了一个 ...

  5. Unix/Linux环境C编程入门教程(5) Red Hat Enterprise Linux(RHEL)环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 通过./a.out ./Y.out执行出结果,证明C++程序编译成功,也就说明li ...

  6. Unix/Linux环境C编程入门教程(4) Debian Linux环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 1.广义的Debian是指一个致力于创建自由操作系统的合作组织及其作品,由于Deb ...

  7. Unix/Linux环境C编程入门教程(3) Oracle Linux 环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 2010年9月,Oracle Enterprise Linux发布新版内核--Un ...

  8. Unix/Linux环境C编程入门教程(2) CentOS环境搭建

    Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 本文就带大家来安装CentOS并且配置好C/C++开发环境,这是一款Linux. ...

  9. Unix/Linux环境C编程入门教程(21) 各个系统HelloWorld跑起来效果如何?

    Unix/Linux家族人员众多,我们无法一一讲解如何配置环境. 本文选定我们在前面安装的RHEL6 RHEL7 MAC10.9.3 Solaris11如何跑起来helloworld RHEL 6 上 ...

随机推荐

  1. 电子工程师名片——FAT16文件系统

    从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机是C8051F320,是一个USB型的单片 ...

  2. Keil C51汉字显示的bug问题(0xFD问题)

    一.缘起 这两天改进MCU的液晶显示方法,采用“即编即显”的思路,编写了一个可以直接显示字符串的程序.如程序调用disstr("我是你老爸");液晶屏上就会显示“我是你老爸”. 二 ...

  3. windbg命令详解

      DLL 该扩展仅在内核模式下使用,即使它是在Ext.dll中的. Windows NT 4.0 Ext.dll Windows 2000 Ext.dll Windows XP和之后 Ext.dll ...

  4. Wap touch flispan demo

    直接上代码了 仔细看看例子就会明白 简单实用 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8& ...

  5. python连续爬取多个网页的图片分别保存到不同的文件夹

      python连续爬取多个网页的图片分别保存到不同的文件夹 作者:vpoet mail:vpoet_sir@163.com #coding:utf-8 import urllib import ur ...

  6. 对中级Linux 用户非常有用的20 个命令

    也许你已经发现第一篇文章非常的有用,这篇文章是继对初级Linux用户非常有用的20个命令的一个延伸. 第一篇文章的目的是为新手准备的而这篇文章则是为了Linux的中高级用户.在这里你将学会如何进行自定 ...

  7. iOS加密个人见解

    说说常用的加密方式 1.单向加密,譬如 md5 .SHA 但是这种单向加密安全性也不高了,现在cpu.gpu都那么强大,运算速度很快,彩虹表 撞库 还是容易被攻破的. 如果非得用的话,可以md5加盐, ...

  8. 怎样使用jetty

    一直都听说jetty跟Tomcat一样,是一个web容器.之前做项目的时候,也使用过jetty,只是当时jetty是作为一个插件,跟maven集成使用的.那个时候,因为是第一次使用jetty,感觉je ...

  9. cocos2d-x结合cocosbuilder,不同屏幕适配小结

    这个问题搞了好几天才解决,在此总结一下: 首先约定只使用一套图片资源同时应用于iphon4和iphon5(测试过在ipad下也能显示正常), 这里我们将需要全屏显示的背景制作为iphon5的尺寸即:1 ...

  10. oracle主机修改IP后客户端无法连接

    无论SQLPLUS还是PLSQL Developer连接均报错: ERROR:ORA-12154: TNS: 无法解析指定的连接标识符 解决方法:修改主机IP后,客户端修改tnsnames文件IP:还 ...