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_USING
,cstdio
是包含了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 木木! @ 2019-11-12 13:55:05
我这里本地跑出来,哪个都是 8.9s 左右,差别一二十毫秒,没有高达一倍的差距吧(
by glassy @ 2019-11-12 14:03:13
@木木! emmmmm也不是严格一倍吧,反正我们的老年教师机真的有高达100+ms的区别……又或者是编译器的问题
by iostream @ 2019-11-12 15:39:24
emmm某次比赛输出大概
不过linux下应该差别不大?
by d3ac @ 2019-11-14 14:32:26
.
by 杨靖浩 @ 2019-12-03 10:29:17
@glassy
这很简单啊!<stdio.h>
是c的头文件,c++也兼容。而<cstdio>
是c++的头文件,c不能用。c++是把c包装了一层,当然要慢点嘛。