`

探究数值比较在程序中执行效率的区别

阅读更多

前言:

众所周知,在C语言中,很多函数都会返回-1以表示函数调用出错。但是很多书籍中(如:UNIX环境高级编程

的很多例子并不使用语句

if (fork() == -1) {
    /* 出错处理 */
}

而是使用

if (fork() < 0) {
    /* 出错处理 */
}

今天我们就比较这两种语句,在运算效率上究竟有什么区别。

 

  • 我们来看看"< 0"和"== -1"的执行效率

源代码如下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/times.h>
#include <unistd.h>

#define TEST_VAL -1
static long clktck = 0; /* 系统每秒时钟滴答数 */

int main(void)
{
    struct tms tmsstart, tmsend;
    clock_t start, end;
    int i, j;
    /* 获取系统每秒时钟滴答数 */
    if ((clktck = sysconf(_SC_CLK_TCK)) < 0) {
        printf("sysconf error: %s\n", strerror(errno));
        exit(0);
    }
    /* 开始时间 */
    printf("val < 0:\n");
    if ((start = times(&tmsstart)) == -1) {
        printf("times error: %s\n", strerror(errno));
        exit(0);
    }

    for (i = 0; i < 100000; i++) {
        if (TEST_VAL < 0) /* 测试条件 */
            ;
        for (j = 0; j < 10000; j++)
            if (TEST_VAL < 0) /* 测试条件 */
               ;
    }
    /* 结束时间 */
    if ((end = times(&tmsend)) == -1) {
        printf("times error: %s\n", strerror(errno));
        exit(0);
    }
    /* 时钟时间 */
    printf("real: %f\n", (end - start) / (double)clktck);
    /* 用户cpu时间 */
    printf("user: %f\n", (tmsend.tms_utime - tmsstart.tms_utime) / (double)clktck);
    exit(0);
}

 

把测试条件分别设为"TEST_VAL < 0"和"TEST_VAL == -1",并分别编译为"t1"和"t2"后运行结果如下图所示


虽然多次运行所消耗的时间略有不同,本人运行多次,然后取平均值后发现,执行"TEST_VAL == -1"所花的时钟时间和用户cpu时间,都略多于"TEST_VAL < 0"

 

  • 我们来观察一下,程序运行的汇编代码

在命令行运行gdb加上-tui选项,进入GDB的TUI模式

 

gdb -tui ./a.out

 

注:要用gdb调试,必须在gcc编译源程序时加上-g选项(如:gcc -g filename)。

 


 

我们都知道,在机器中,机器数的最高有效位为符号位。如果一个数最高有效位为1,则表示该数为负;如果一个数最高有效位为0,则表示该数为正。假设一台机器的int类型字长为8位,那么-1在该机器中将表示为0xff(二进制表示为11111111)。

 

总结:

CMP oprand1,oprand2

通过前面的分析,我们有理由猜想,机器在内部执行cmp指令时,会进行一定程度的优化。 

当测试操作数是否小于0时,机器只检查该操作数的最高有效位是否为1;而当机器在测试操作数是否等于-1时,需要将该操作数与-1逐位相与。这一点区别很可能是造成"TEST_VAL < 0"和"TEST_VAL == -1"执行效率不同的原因。

 

结束语:

以上测试用例可能过于片面,无法反映真实的情况。博主在此抛砖迎玉,如有对此课题感兴趣的读者,可以和博主一起探讨。由于本人水平所限,如有错误,欢迎批评指正。

 

参考文献:

1. http://stackoverflow.com/questions/22380693/what-does-0x4rbp-means-in-gdb-disassembly

2. https://sourceware.org/gdb/onlinedocs/gdb/TUI.html

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

  • 大小: 19.1 KB
  • 大小: 8.1 KB
  • 大小: 47.8 KB
  • 大小: 81.5 KB
2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics