测试c语言函数调用性能因素

函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作。

操作:

1,               调用函数帧指针(函数参数,局部变量,栈帧状态值,函数返回地址)入栈,栈指针自减

2,               保存调用函数的状态数据入寄存器

3,               被调用函数帧指针入栈,执行当前的被调用函数

4,               被调用函数执行结束,退栈,返回到调用函数的帧指针,从寄存器中恢复当时状态数据

5,               继续执行调用函数,直至结束

即整个调用操作有一个压栈出栈,保存和恢复状态数据的过程。而系统栈内存是有默认的固有大小。有多少次函数调用就会分配多少栈帧。故,函数调用性能影响有如下因素:

1,函数递归层数;

2,参数个数(参数签名所占内存大小)

2.1同类型不同参数个数;

2.2同参数个数不同参数类型;

2.3同参数类型同参数个数,但参数类型所占内存大小不同;

3,函数栈大小,即函数局部变量所占栈大小。

为了测试C语言函数调用性能(时间消耗)因素,编写了一个简单程序运行在如下环境中:

Windows7操作系统上的Vmware虚拟机中的ubuntu系统

在函数调用的开始与结束处,用time.h中的clock()函数返回CPU时钟计时单位数(下表中的starttime和endtime),用durationtime=endtime-starttime表示函数调用的时间消耗。如下:

clock_t  starttime=clock();

函数调用…

clock_t  endtime=clock();

//除以CLOCKS_PER_SEC,得到以秒为单位的时间结果

double durationtime=(double)(endtime-starttime)/CLOCKS_PER_SEC;

一.函数递归层数


递归层数


参数个数


函数栈大小


starttime


endtime


durationtime(秒)


10


5


1024


951


985


0.000034


10


5


1024


925


961


0.000036


10


5


1024


957


992


0.000035


20


5


1024


950


1004


0.000054


20


5


1024


897


952


0.000055


20


5


1024


996


1045


0.000049


30


5


1024


1075


1145


0.00007


30


5


1024


1031


1096


0.000065


30


5


1024


976


1040


0.000064


50


5


1024


1068


1167


0.000099


50


5


1024


1097


1196


0.000099


50


5


1024


1232


1331


0.000099


100


5


1024


940


1463


0.000523


100


5


1024


939


1113


0.000174


100


5


1024


938


1118


0.00018


100


5


1024


946


1144


0.000198


100


5


1024


968


1148


0.00018


500


5


1024


1033


2047


0.001014


500


5


1024


882


1983


0.001101


500


5


1024


801


1762


0.000961


500


5


1024


819


1842


0.001023


500


5


1024


859


1896


0.001037


1000


5


1024


983


3530


0.002547


1000


5


1024


936


3967


0.003031


1000


5


1024


917


3223


0.002306


1000


5


1024


1424


3500


0.002076


1000


5


1024


1008


3496


0.002488


1000


5


1024


963


3004


0.002041


1500


5


1024


763


4971


0.004208


1500


5


1024


903


7195


0.006292


1500


5


1024


1035


5375


0.00434


1500


5


1024


851


4375


0.003524


1500


5


1024


740


4002


0.003262


2000


5


1024


1065


5891


0.004826


2000


5


1024


1129


5701


0.004572


2000


5


1024


975


5019


0.004044


2000


5


1024


976


6288


0.005312


2000


5


1024


1017


7311


0.006294


3000


5


1024


762


11168


0.010406


3000


5


1024


832


8093


0.007261


3000


5


1024


1000


10505


0.009505


3000


5


1024


849


12248


0.011399


3000


5


1024


936


11466


0.01053


5000


5


1024


1144


18218


0.017074


5000


5


1024


1084


18654


0.01757


5000


5


1024


913


18257


0.017344


5000


5


1024


905


22046


0.021141


5000


5


1024


1043


18823


0.01778


6000


5


1024


847


29291


0.028444


6000


5


1024


824


21972


0.021148


6000


5


1024


743


20547


0.019804


6000


5


1024


890


19888


0.018998


6000


5


1024


810


19193


0.018383


7000


5


1024


962


23460


0.022498


7000


5


1024


1040


21367


0.020327


7000


5


1024


986


20902


0.019916


7000


5


1024


1017


24210


0.023193


7000


5


1024


977


21932


0.020955

上表测试平均值如下:


递归层数


参数个数


函数栈大小


Avrg_durationtime(微秒)[平均值]


每次递归平均值(微秒)


10


5


1024


35


3.5


20


5


1024


52.66


2.633


30


5


1024


66.33


2.211


50


5


1024


99


1.98


100


5


1024


251


2.51


500


5


1024


1027.2


2.0544


1000


5


1024


2414.83


2.414


1500


5


1024


4325.2


2.883


2000


5


1024


5009.6


2.5048


3000


5


1024


9820.2


3.2734


5000


5


1024


18181.8


3.63636


6000


5


1024


21355.4


3.5592


7000


5


1024


21377.8


3.0597

根据平均值表绘折线图如下:(系统在递归层数超过7000会栈溢出)

在同函数参数个数同函数栈大小的情况下,每次函数调用平均时间消耗图:

二.参数个数


递归层数


参数个数


函数栈大小


starttime


endtime


durationtime(秒)


2000


1


1024


904


8318


0.007414


2000


1


1024


982


8508


0.007526


2000


1


1024


968


8361


0.007393


2000


1


1024


1212


8101


0.006889


2000


1


1024


1269


5964


0.004695


2000


1


1024


906


9532


0.008626


2000


1


1024


786


8110


0.007324


2000


1


1024


929


7708


0.006779


2000


1


1024


895


7900


0.007005


2000


1


1024


959


4732


0.003773


2000


3


1024


1569


9858


0.008289


2000


3


1024


999


6132


0.005133


2000


3


1024


1083


6673


0.00559


2000


3


1024


1170


8269


0.007099


2000


3


1024


946


5683


0.004737


2000


3


1024


846


6908


0.006062


2000


3


1024


828


7849


0.007021


2000


3


1024


977


7079


0.006102


2000


3


1024


845


8521


0.007676


2000


3


1024


1047


8368


0.007321


2000


5


1024


911


7754


0.006843


2000


5


1024


1173


5677


0.004504


2000


5


1024


1477


12230


0.010753


2000


5


1024


908


5397


0.004489


2000


5


1024


988


10145


0.009157


2000


5


1024


759


8113


0.007354


2000


5


1024


885


8954


0.008069


2000


5


1024


917


6160


0.005243


2000


5


1024


831


6685


0.005854


2000


5


1024


900


7814


0.006914


2000


10


1024


1359


6479


0.00512


2000


10


1024


1678


7318


0.00564


2000


10


1024


1956


9234


0.007278


2000


10


1024


964


8546


0.007582


2000


10


1024


939


6501


0.005562


2000


10


1024


829


7508


0.006679


2000


10


1024


891


8894


0.008003


2000


10


1024


877


7126


0.006249


2000


10


1024


930


6761


0.005831


2000


10


1024


920


7762


0.006842

上表测试平均值如下:


递归层数


参数个数


函数栈大小


Avrg_durationtime(微秒)[平均值]


每次递归平均值(微秒)


2000


1


1024


6742.4


3.3712


2000


3


1024


6503


1.0838*3=3.2514


2000


5


1024


6918


0.6918*5=3.459


2000


10


1024


6478.6


0.32393*10=3.2393

根据平均值表绘折线图如下:

每个参数每次递归平均值折线图:

结论:在同函数栈大小和同递归层数的情况下,函数参数个数没造成规模性差异的时候,平均时间消耗几乎相近。

三.函数栈大小


递归层数


参数个数


函数栈大小


starttime


endtime


durationtime(秒)


2000


5


1024


1242


10890


0.009648


2000


5


1024


1337


14279


0.012942


2000


5


1024


1069


8970


0.007901


2000


5


1024


1023


12279


0.011256


2000


5


1024


970


8142


0.007172


2000


5


2048


1177


14290


0.013113


2000


5


2048


984


16388


0.015404


2000


5


2048


1051


12327


0.01276


2000


5


2048


899


15451


0.014552


2000


5


2048


1372


14674


0.013302


2000


5


3072


1238


15792


0.014554


2000


5


3072


914


13615


0.012701


2000


5


3072


1406


17867


0.016461


2000


5


3072


978


17876


0.016898


2000


5


3072


1008


16438


0.01543


2000


5


4096


1242


10890


0.009648


2000


5


4096


1337


14279


0.012942


2000


5


4096


1069


8970


0.007901


2000


5


4096


1023


12279


0.011256


2000


5


4096


970


8142


0.007172

上表测试平均值如下:


递归层数


参数个数


函数栈大(int)


Avrg_durationtime(微秒)[平均值]


每个参数每次递归平均值(微秒)


2000


5


1024


5009.6


2.5048/5=0.50096


2000


5


2048


9783.8


4.8919/5=0.97838


2000


5


3072


13826.2


6.9131/5=1.38262


2000


5


4096


15208.8


7.6044/5=1.52088

根据平均值表绘折线图如下:(函数栈大小超过5120会栈溢出)

每个参数每次递归平均值折线图:

结论:单个函数参数单词函数调用所需要的时间消耗与函数栈大小几乎成对等倍数增长。

四.  结论

1,        在函数参数和函数栈大小一定时,函数递归调用的时间消耗在一定递归层数范围内与递归层数呈现正相关关系。

2,        在函数递归层数和函数参数个数一定时,函数递归调用的时间消耗在一定函数栈大小范围内与函数栈大小呈现正相关关系。

3,        在函数参数个数没有造成规模性差异的情况下(即函数签名所占栈内存不大时),函数参数个数所造成的时间消耗几乎相近。

4,        在函数参数个数没有造成规模性差异的情况下(即函数签名所占栈内存不大时),函数调用层数和函数栈大小对函数调用的时间消耗产生明显影响。

:1,由于程序测试的操作系统环境的差异,可能会导致数据误差。

2,计时方法的差异,可能会导致数据误差。

3,个人编码能力也可能导致数据误差。

时间: 2024-10-03 08:53:42

测试c语言函数调用性能因素的相关文章

测试c语言函数调用性能因素之测试二

函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作. 操作: 1,               调用函数帧指针(函数参数,局部变量,栈帧状态值,函数返回地址)入栈,栈指针自减 2,               保存调用函数的状态数据入寄存器 3,               被调用函数帧指针入栈,执行当前的被调用函数 4,               被调用函数执行结束,退栈,返回到调用函数的帧指针,从寄存

测试c语言函数调用性能因素之测试三

函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作. 操作: 1,               调用函数帧指针(函数参数,局部变量,栈帧状态值,函数返回地址)入栈,栈指针自减 2,               保存调用函数的状态数据入寄存器 3,               被调用函数帧指针入栈,执行当前的被调用函数 4,               被调用函数执行结束,退栈,返回到调用函数的帧指针,从寄存

C++应用程序性能优化(三)——C++语言特性性能分析

C++应用程序性能优化(三)--C++语言特性性能分析 一.C++语言特性性能分析简介 通常大多数开发人员认为,汇编语言和C语言比较适合编写对性能要求非常高的程序,C++语言主要适用于编写复杂度非常高但性能要求并不是很高的程序.因为大多数开发人员认为,C++语言设计时因为考虑到支持多种编程模式(如面向对象编程和范型编程)以及异常处理等,从而引入了太多新的语言特性.新的语言特性往往使得C++编译器在编译程序时插入了很多额外的代码,会导致最终生成的二进制代码体积膨胀,而且执行速度下降.但事实并非如此

PHP 使用Apache 中的ab 测试网站的压力性能

打开Apache服务器的安装路径(我用的是 WampServer),在bin目录中有一个ab.exe的可执行程序,它就是要介绍的压力测试工具. 在Windows系统的命令行下,进入ab.exe程序所在目录,执行ab.exe程序.注意直接双击无法正确运行. d:(回车/进入D盘) cd wamp\bin\apache\Apache2.4.4\bin(回车/进入 bin目录) ab(回车/) 如果看到下列一些帮助信息就说明成功启动ab     开始启动ab 压力测试 ab -n 5000 -c 20

C语言函数调用栈(三)

6 调用栈实例分析 本节通过代码实例分析函数调用过程中栈帧的布局.形成和消亡. 6.1 栈帧的布局 示例代码如下: 1 //StackReg.c 2 #include <stdio.h> 3 4 //获取函数运行时寄存器%ebp和%esp的值 5 #define FETCH_SREG(_ebp, _esp) do{ 6 asm volatile( 7 "movl %%ebp, %0 \n" 8 "movl %%esp, %1 \n" 9 : "

编写自动测试c语言程序的shell脚本

目前经常用vim编写一些c语言程序,写好了程序一般都得进行一些测试,当然我们可以进行一些常规的手动测试.心里一想,如果能够用shell脚本编写一个能自动测试c语言程序就好了. 为了试一试这样的想法,找了一个c语言程序题目: [一球从 100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10 次落地时,共经过多少米?第10 次反弹多高? ] 根据这样的要求我编写了一个解决这个问题的程序: #include <stdio.h> #include <stdlib.h> #

SQLIO 模拟随机或者顺序的方式来测试磁盘IO的性能

SQLIO 功能:磁盘IO压力测试工具,SQLIO主要是模拟随机或者顺序的方式来测试磁盘IO的性能. SQLIO Disk Subsystem Benchmark Tool工具下载地址: http://www.microsoft.com/en-us/download/details.aspx?id=20163 RAID存储技术在SQL Server服务器上已经被广泛使用,对于存储介质,有很多层面的硬件和固件,以及存储管理软件配置.如果设置不恰当,同样的硬件最后的效能会差别很大. 微软提供了一个工

测试EF6.1.3性能

公司原来用nhibernate,现在考虑要不要用EF.所以就产生了测试这两个性能的要求.对比两个ORM工具的性能,主要是对比ORM配置和启动速度:建表速度:插入行速度:修改行速度以及查询速度,删除用的比较少,就不测试了. 测试表结构 public class School { public Guid ID { get; set; } public string Name { get; set; } public int AllPersonCount { get; set; } } public

ab工具使用(测试平台的并发性能)简单介绍一下

Apache -- ab工具主要测试网站的(并发性能) 这个工具非常的强大. 基本语法 :   cmd>ab.exe –n 请求总次数  -c 并发数 请求页面的url    进入到ab.exe目录 举例:  cmd>ab.exe –n 10000 –c 100 http://localhost/test.php 简单test结果简单介绍一下: ab工具使用(测试平台的并发性能)简单介绍一下