[研究C++与C语言简单的输出语句的效率]

某回工作内容需要对C++输入输出流的速度进行一次测算,期间发现了一个有趣的现象,故在此进行分享。

准备了四分代码,他们都是简单的1+1进行直接的输出:

分别为 C++使用解除输入输出流绑定, C++不使用解除绑定,C++直接使用C语言的printf,C语言使用printf。完成测试。

代码如下:

【 C++使用解除输入输出流绑定】

#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    clock_t start,stop;
    start=clock();

    for(int i=0;i<=1e7;i++){
        cout<<i<<endl;
    }

    stop=clock();
    printf("总计用时为:%f\n",(double)(stop-start)/CLOCKS_PER_SEC);
    return 0;
}
//C++ 解除绑定

【 C++不使用解除绑定】

#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int main(){耗时
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);

    clock_t start,stop;
    start=clock();

    for(int i=0;i<=1e7;i++){
        cout<<i<<endl;
    }

    stop=clock();
    printf("总计用时为:%f\n",(double)(stop-start)/CLOCKS_PER_SEC);
    return 0;
}
//C++ 不接触绑定

【C++直接使用C语言的printf】

#include<iostream>
#include<cstdio>
#include<ctime>
using namespace std;
int main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);

    clock_t start,stop;
    start=clock();

    for(int i=0;i<=1e7;i++){
        printf("%d\n",i);
    }

    stop=clock();
    printf("总计用时为:%f\n",(double)(stop-start)/CLOCKS_PER_SEC);
    return 0;
}
//C++ 使用printf

【C语言使用printf】

#include<stdio.h>
#include<time.h>
int main(){
    
    clock_t start,stop;
    start=clock();

    int i;
    for(i=0;i<=1e7;i++){
        printf("%d\n",i);
    }

    stop=clock();
    //printf("总计用时为:%f\n",(double)(stop-start)/CLK_TCK);      //Windows 下使用
    printf("总计用时为:%f\n",(double)(stop-start)/CLOCKS_PER_SEC); //Linux 下使用
    return 0;
}
//C语言使用printf

使用clock()函数进行计时,在输出测试代码运行前进行标记计时,结束后同样进行标记计时,将两次不同的计时功能相减后除以CLK_TCK就可以得到以秒为单位的耗时,在LINUX系统下需要把CLK_TCK更换为CLOCKS_PER_SEC才可以正常运行,否则提示报错CLK_TCK 未定义。

按照个人所学,代码的运行速度应该是(以耗时为标准) C++不解除绑定耗时 > C++解除绑定耗时 > C++使用printf耗时 > C语言使用printf耗时 ,C语言应该是最快的。

因此分别在WINDOWS系统下以一万数据(1e5)为例,进行了一次简单的测试,为了排除特殊情况每个情况又测试了三次,在WINDOWS下得出的结论却为:

C++使用printf耗时 > C++不解除绑定耗时 > C++解除绑定耗时 >  C语言printf耗时

在平时的ACM/蓝桥杯等这些训练中,给我的常规映像应该是C++如果不会解除绑定,使用printf是速度相对而言较快的,然而现在的情况却是很明显的C++直接使用printf最慢。

为了模拟真实的测评机(姬)情况,我转到自己的LINUX系统上进行运行,这里先写明系统和编译器环境:【系统:ElementaryOS5.0 (ubuntu18.04改版系统) 编译器 gcc 5.5.0 , g++ 5.5.0 】

结果很意外,同样的电脑,Windows下运行的输出优化到Linux完全变成了另外一种情况,在一万数据的情况下,这些将近一分钟运行出来结果的代码,统统运行不到半秒钟就运行结束了,因此我将数据翻了一百倍到一百万的数据量(1e7)进行再度的测试。以下是三次测试的结果

我们现实中编写算法的代码几乎都是在WINDOWS平台,而真正提交测评则全是LINUX平台,可以见的,在LINUX下的运行效果,他们都是相当的,但是细看数据,还是有略微的差别,在一百万输出数据的情况下,解除输出绑定的C++依旧是略快一筹,如果你是一个追求极致的优化党,请不要忽视这一丁点的优化,积少成多,水滴石穿。

分类: C++

2 条评论

lei · 2020年12月8日 下午9:37

学到了,谢谢博主。请问如果将输入流与输出流绑定在一起有什么作用意义呢?

    Mustenaka · 2020年12月11日 上午9:11

    绑定之后混合使用printf和cout以及混合使用SCANF与cin不会出现那么多的编译通过实际上的意想不到的错误,实际上这个解绑就是把C++的输出(输入)与C语言的输出(输入)公用一块内存给割裂开来,以达到加速的作用

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注