关于cstdio和stdio.h的scanf效率

P1001 A+B Problem

glassy @ 2019-11-12 13:34:17

校内的模拟赛遇到了这样的题面

本题可能涉及到大量输入,请妥善选择输入方式。对于C++,一个简单有效的方式是使用stdio.h 文件下的输入而非cstdio;VC++则不需要考虑这一点。

然后实测也确实快了(近乎一倍)。

蒟蒻如何想也不清楚为什么会有区别,因为在cstdio的定义中有这样一句话

#ifdef _STD_USING
 #undef _STD_USING
  #include <stdio.h>
 #define _STD_USING

#else /* _STD_USING */
 #include <stdio.h>
#endif /* _STD_USING */

所以理论上不管有没有定义_STD_USINGcstdio是包含了stdio.h的。

为了弄清楚到底为什么,蒟蒻尝试观察它们的汇编代码,结果,两者的汇编代码几乎完全一致(唯一的不同是两者的文件名称) 源代码如下:

//stdio.cpp
#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
}
//cstdio.cpp
#include<cstdio>
int main(){
    int n;
    scanf("%d",&n);
}

汇编代码如下

    .file   "stdio.cpp"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "%d\0"
    .text
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
LFB8:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    call    ___main
    leal    28(%esp), %eax
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _scanf
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE8:
    .ident  "GCC: (GNU) 4.8.1"
    .def    _scanf; .scl    2;  .type   32; .endef
    .file   "cstdio.cpp"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "%d\0"
    .text
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
LFB8:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    call    ___main
    leal    28(%esp), %eax
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _scanf
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE8:
    .ident  "GCC: (GNU) 4.8.1"
    .def    _scanf; .scl    2;  .type   32; .endef

经比对几乎完全一致,然而编译出的exe文件大小却不一样。

stdio.exe:102KB
cstdio.exe:109KB

蒟蒻想问一下它们效率到底差在哪里了,以及为何同一份汇编代码会得到不同的机器代码。

感激不尽。


by tiger0133 @ 2019-11-12 13:34:45

有意思的问题,铜球


by WYXkk @ 2019-11-12 13:35:54

有意思,但是我看不懂汇编


by _H1kar1 @ 2019-11-12 13:36:31

有意思的问题,铜球qwq


by zl_just @ 2019-11-12 13:37:17

有意思的问题,所以我选择快读


by glassy @ 2019-11-12 13:37:21

我也看不懂汇编QAQ,只看着完全一样……


by 木木! @ 2019-11-12 13:40:22

不知道为什么,我这里编译并 fc 是有差距的(

要说什么影响的话,估计是全局变量的构造和析构带来的影响(


by 木木! @ 2019-11-12 13:41:36


by StudyingFather @ 2019-11-12 13:43:09

@glassy

预编译指令 `include` 将会把要包含的文件直接复制到相应位置,也就是说 `#include <cstdio>` 将会直接将 `cstdio` 的内容复制到源文件的开头位置。

因此编译出来的文件大小会有差别。

by StudyingFather @ 2019-11-12 13:43:38

(别问我为啥要全用代码框框起来,因为不这么框就发不出去


by 倍镜 @ 2019-11-12 13:43:56

我个蒟蒻看不懂T_T

@glassy 还说自己蒟蒻


| 下一页