标签:

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

操作:

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,个人编码能力也可能导致数据误差。

标签:

C语言C6292错误,测试c语言函数调用性能因素相关推荐

  1. c语言编译错误 原文,C语言常见错误与警告

    C语言常见错误与警告 C语言常见错误与警告C语言常见错误: 1 invalid type argument of '->' (have 'struct qstr_xid_element') 这种 ...

  2. 利用c语言设置密码错误循环,c语言运算符优先级与while循环案例

    sizeof可以获取数据类型的内存中的大小(字节) #include #include // standared 标准 // input output 输入/输出 // header 头 .h头文件 ...

  3. c语言多实力测试,C语言 多线程测试

    1.CreateThread 在主线程的基础上创建一个新线程 2.WaitForMultipleObjects 主线程等待子线程 3.CloseHandle 关闭线程 // testThread.cp ...

  4. c语言中错误executing,C语言编程中常见问题解读.doc

    C语言编程中常见问题解读 为什么vc6打开的文件却不能编译1 为什么一个vc6工程中有两个main函数不能编译成功?我想写两个程序怎么办?2 为什么v6不能编译程序,生成信息说compile和link ...

  5. c语言scanf错误c4996,C语言杂谈(一)scanf()、scanf_s()与错误 C4996

    错误 C4996 初学C语言时,第一个接触到的I/O函数便是scanf()了.但在高版本的 Visual Studio (包括但不限于2015.2013.2012)编译代码时,却会出现意想不到的错误. ...

  6. c语言scanf错误c4996,C语言常见错误杂谈(一)scanf()、scanf_s()与错误 C4996与解决方法...

    错误 C4996 初学C语言时,第一个接触到的I/O函数便是scanf()了.但在高版本的 Visual Studio (包括但不限于2015.2013.2012)编译代码时,却会出现意想不到的错误. ...

  7. c语言scanf错误c4996,C语言杂谈(一)scanf()、scanf_s()与错误 C4996(示例代码)

    错误 C4996 初学C语言时,第一个接触到的I/O函数便是scanf()了.但在高版本的 Visual Studio (包括但不限于2015.2013.2012)编译代码时,却会出现意想不到的错误. ...

  8. c语言分段错误空指针,C语言空指针总结 - 祂的小哥哥的个人空间 - OSCHINA - 中文开源技术交流社区...

    空指针就是指向不可访问区域的的指针,它的值为NULL,地址一般是内存的首地址.详情见代码1.2及其运行结果. NULL是标准库定义的等于0的常量符号. 不可访问和内存的划分有关.系统会在每个程序被调用 ...

  9. 创建c语言编译错误,创建C语言项目时,无法编译成*.exe文件,提示系统找不到指定的文件...

    你好: 这是配置管理器,没看懂 https://skydrive.live.com/redir?resid=56EDD5214D16058E!172&authkey=!AFt6lfaQijGu ...

最新文章

  1. 计算机系男同学追班里一女同学,未果......
  2. Windows Server 2008 定义用户桌面图标
  3. 46亿一辆的戴森电动车,「卖」给英国首富了
  4. php动态页面加载慢,通过动态加载JS文件提升网站访问速度
  5. 【信息系统项目管理师】第5章-项目范围管理 知识点详细整理
  6. 咕咕(数位dp+AC自动机)
  7. easyUI datagrid 重复发送URL请求
  8. socket调试工具、socket调试软件、tcp调试工具、tcp调试软件(sokit)
  9. 4.4 输入法图片 android,支持安卓4.4!搜狗输入法5.1新版发布
  10. CKEditor配置使用
  11. mybatis plus(包米豆)json存储Mysql数据库
  12. 靠谱的企业并购流程|塔米狗
  13. Macbook Pro(无法完全)通过序列号与激活时间辨别是否为翻新机
  14. 一度智信:分析拼多多人群定位
  15. android数据写入文件格式,Android 本地文件保存数据(2020-08-07)
  16. win10证书服务器不可用,win10系统弹安全警报安全证书的吊销信息不可用的解决方法...
  17. python获取kegg pathway map的信息
  18. 大数据项目篇--电商用户画像
  19. arduino智能闹钟_【Arduino综合项目】小闹钟
  20. java按钮按行放置_java 放置按钮

热门文章

  1. 2018-09-06 Java实现英汉词典API初版发布在Maven
  2. matlab互相关检测器,自相关函数和互相关函数的利用MATLAB计算和作图
  3. Pytorch基础——torch.randperm
  4. LeetCode——998.最大二叉树 II
  5. 重识Nginx - 09 使用Nginx内置变量$limit_rate实现带宽限速
  6. GraphScope、Neo4j与TigerGraph单机环境下性能对比
  7. 常见的OutOfMemoryError原因及解决方案
  8. [导入]网页制作万花筒
  9. 知识小结------数据分析------Bonferroni correction(邦费罗尼校正)
  10. java duplicate entry_java向数据库插入数据时的错误: Duplicate entry '' for key 'PRIMARY' 问题解决...