- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
是<cstdio>
吗C++ 中的 header 包含与 <stdio.h>
相同的功能但输入 std
命名空间?
我在使用 mingw-w64 编译的程序中遇到了奇怪的效率问题,它比在 linux 上慢十倍以上。经过一些测试,我发现问题出在 sprintf
中。 .
然后我做了如下测试:
#include <stdio.h>
// #include <cstdio>
// using std::sprintf;
int main () {
int i;
for (i = 0; i < 500000; i++){
char x[100];
sprintf(x, "x%dx%dx", i, i<<2);
}
}
使用 <stdio.h>
编译时它比使用 <cstdio>
快 15 倍.这是时间:
$ time ./stdio
real 0m0.557s
user 0m0.046s
sys 0m0.046s
$ time ./cstdio
real 0m7.465s
user 0m0.031s
sys 0m0.077s
$ g++ --version
g++.exe (rubenvb-4.8-stdthread) 4.8.1 20130324 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
更新 1:我进一步对不同的 mingw-w64 构建(rubenvb、drangon 和 mingw-build)进行了计时,发现所有 32 位版本都使用 <cstdio>
计时 4.x 秒和 64 位版本 7.x~8.x 秒。所有版本都使用 <stdio.h>
定时0.4~0.6秒左右。
更新 2:我反汇编了 gdb 中的主要函数,发现只有一行不同:<stdio.h>
版本调用 callq 0x4077c0 <sprintf>
但是 <cstdio>
版本调用 callq 0x407990 <_Z7sprintfPcPKcz>
.
sprintf
包含:
0x00000000004077c0 <+0>: jmpq *0x7c6e(%rip) # 0x40f434 <__imp_sprintf>
0x00000000004077c6 <+6>: nop
0x00000000004077c7 <+7>: nop
正在关注 __imp_sprintf
我到达了sprinf
里面msvcrt.dll
.
_Z7sprintfPcPKcz
包含一些 mingw 代码:
0x0000000000407990 <+0>: push %rbp
0x0000000000407991 <+1>: push %rbx
0x0000000000407992 <+2>: sub $0x38,%rsp
0x0000000000407996 <+6>: lea 0x80(%rsp),%rbp
0x000000000040799e <+14>: mov %rcx,-0x30(%rbp)
0x00000000004079a2 <+18>: mov %r8,-0x20(%rbp)
0x00000000004079a6 <+22>: mov %r9,-0x18(%rbp)
0x00000000004079aa <+26>: mov %rdx,-0x28(%rbp)
0x00000000004079ae <+30>: lea -0x20(%rbp),%rax
0x00000000004079b2 <+34>: mov %rax,-0x58(%rbp)
0x00000000004079b6 <+38>: mov -0x58(%rbp),%rdx
0x00000000004079ba <+42>: mov -0x28(%rbp),%rax
0x00000000004079be <+46>: mov %rdx,%r8
0x00000000004079c1 <+49>: mov %rax,%rdx
0x00000000004079c4 <+52>: mov -0x30(%rbp),%rcx
0x00000000004079c8 <+56>: callq 0x402c40 <__mingw_vsprintf>
0x00000000004079cd <+61>: mov %eax,%ebx
0x00000000004079cf <+63>: mov %ebx,%eax
0x00000000004079d1 <+65>: add $0x38,%rsp
0x00000000004079d5 <+69>: pop %rbx
0x00000000004079d6 <+70>: pop %rbp
为什么 cstdio
使用不同的(并且慢得多的)函数?
最佳答案
libstdc++ 确实在构建期间定义了 __USE_MINGW_ANSI_STDIO
(config/os/mingw32-w64/os_defines.h
),这将打开 mingw sprintf
wrapper 。正如@Michael Burr 指出的那样,这些包装器的存在是为了与 C99/GNU99 兼容。
您的测试未定义 __USE_MINGW_ANSI_STDIO
,因此您不会获得包含 stdio.h
的包装器。但由于它是在构建 libstdc++ 时定义的,您将通过 cstdio
获得它。但是,如果您在包含 stdio.h
之前自己定义它,您将再次获得包装器。
所以你实际上得到了不同的实现,cstdio std::sprintf
不一定与 stdio.h sprintf
相同,至少在涉及到明威。
这是一个测试。首先是来源:
#ifdef USE_STDIO
#include <stdio.h>
#else
#include <cstdio>
using std::sprintf;
#endif
int main () {
int i;
for (i = 0; i < 500000; i++){
char x[100];
sprintf(x, "x%dx%dx", i, i<<2);
}
}
结果:
$ g++ -o test_cstdio.exe test.cc
$ g++ -o test_stdio.exe -DUSE_STDIO test.cc
$ g++ -o test_stdio_wrap.exe -DUSE_STDIO -D__USE_MINGW_ANSI_STDIO test.cc
$ for x in test_*.exe; do ( echo $x; objdump -d $x | grep sprintf; echo ); done
test_cstdio.exe
40154a: e8 41 64 00 00 callq 407990 <_Z7sprintfPcPKcz>
0000000000402c40 <__mingw_vsprintf>:
0000000000407990 <_Z7sprintfPcPKcz>:
4079c8: e8 73 b2 ff ff callq 402c40 <__mingw_vsprintf>
test_stdio.exe
40154a: e8 71 62 00 00 callq 4077c0 <sprintf>
00000000004077c0 <sprintf>:
4077c0: ff 25 6e 6c 00 00 jmpq *0x6c6e(%rip) # 40e434 <__imp_sprintf>
test_stdio_wrap.exe
40154a: e8 41 64 00 00 callq 407990 <_Z7sprintfPcPKcz>
0000000000402c40 <__mingw_vsprintf>:
0000000000407990 <_Z7sprintfPcPKcz>:
4079c8: e8 73 b2 ff ff callq 402c40 <__mingw_vsprintf>
关于c++ - mingw-w64 : slow sprintf in <cstdio>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17236352/
我正在尝试创建一个迭代器来遍历我的文件。我的文件是二进制的,里面有 int 值,所以在我看来,它应该像那样工作。但是我收到错误提示“无效使用数据成员‘IntFile::file’”所以我在代码中标记了
我有一个要写入数据的文件,使用 cstdio 中的函数。我想确保文件已成功写入文件而没有任何中断,因此我知道稍后读取文件时会从文件中得到什么。我打算这样做的方法是,首先将 8 个字节的清零数据写入文件
下面的 C 代码有什么问题? (更新) int nfds = 0; char c[2] = " "; char ans[2] = " "; printf("Test p or s [p,s]: p?
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
当我添加 #include 时,我在 cstdio 中遇到了很多错误到 C 程序。 c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\in
我有一些数据使用 cin/in 太慢了。每行三个整数: 1 2 2 3 4 1 5 6 122 6 4 7 如何读入循环中的每一行,以获得结果(对于第一次迭代): x==1; y==2; z==2;
我正在上我的第一门 c++ 课(我在第 6 周。) 我使用了 getchar(),根据我能找到的所有引用资料,它位于 cstdio(或 stdio 或 stdio.h)中。只是为了看看会发生什么,我注
我正在寻找一个类似于 iostreams 的库,因为它执行转换,并允许写入内存缓冲区、文件和控制台。但是,我想要一些类型安全的东西,就像 iostream 一样。有没有真正的图书馆可以做到这一点? 能
我刚刚了解到ios_base::sync_with_stdio函数的存在,它基本上可以让你关闭(或者如果你已经关闭它就打开)iostream之间的同步在 C++ 中使用的 code> 流和作为标准 C
我从 cstdio 的 c++ 引用中看到这一行: 库的每个元素都在 std 命名空间中定义。但我尝试了代码: std::printf("hello world"); printf("hello wo
这个问题已经有答案了: Correct format specifier for double in printf (5 个回答) 已关闭 6 年前。 使用 cstdio header 的 doubl
下面的 c++ 程序无法读取文件。我知道使用 cstdio 不是很好的做法,但我已经习惯了,它应该可以正常工作。 $ ls -l l.uyvy -rw-r--r-- 1 atilla atilla 6
我正在尝试使用 C++ 习惯用法将字符写入 cout,但我在任何 C++ 标准库中都找不到字符格式化程序。 最佳答案 字符自动格式化为 %c。要将整数打印为 char(如果你真的想要),你可以转换它:
_gnu_cxx::snprintf has not been declared 当我在我的 cpp 中包含字符串时。此错误位于此行: using ::__gnu_cxx::snprintf; cst
是吗C++ 中的 header 包含与 相同的功能但输入 std命名空间? 我在使用 mingw-w64 编译的程序中遇到了奇怪的效率问题,它比在 linux 上慢十倍以上。经过一些测试,我发现问题
假设我有这样的代码片段: #include using namespace std; int main(int argc, char *argv[]) { printf("%d",5); } 它在我
我正在尝试编写一个简单的程序,以 1024 字节为单位从文件(输入)读取数据,然后将数据写入另一个文件(输出)。该程序到目前为止工作,但我遇到的问题是,如果它到达文件末尾并且最后一次读取不是 1024
以下代码会引发许多错误: namespace ns1 { #include ... } /usr/include/c++/4.9/cstdlib:118: error: '::d
所以这个问题只是出于好奇。我有一些小程序: #include void print(){ printf("abc"); } // don't care about main, I'm not gon
我正在编写使用 C++ 库中定义的一些类的 Cocoa 代码。我给文件名加上扩展名 .mm,通常一切正常。 但并非总是如此。有时 Xcode 4 让我失望:“词法或预处理器问题:‘cstdio’未找到
我是一名优秀的程序员,十分优秀!