Note that there are some explanatory texts on larger screens.

plurals
  1. POmingw-w64: slow sprintf in <cstdio>
    primarykey
    data
    text
    <p>Is that <code>&lt;cstdio&gt;</code> header in C++ contains just the same functions as <code>&lt;stdio.h&gt;</code> but put in <code>std</code> namespace?</p> <p>I experienced strange efficiency problems in my program compiled with mingw-w64, which is more than ten times slower then on linux. After some test I found that the problem is in <code>sprintf</code>.</p> <p>Then I did the following test:</p> <pre><code>#include &lt;stdio.h&gt; // #include &lt;cstdio&gt; // using std::sprintf; int main () { int i; for (i = 0; i &lt; 500000; i++){ char x[100]; sprintf(x, "x%dx%dx", i, i&lt;&lt;2); } } </code></pre> <p>When compiled with <code>&lt;stdio.h&gt;</code> it is 15 times faster then using <code>&lt;cstdio&gt;</code>. Here is the timing:</p> <pre><code>$ 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. </code></pre> <p><strong>UPDATE 1</strong>: I further timed with different mingw-w64 build (rubenvb, drangon, and mingw-build), and find that all 32bit version using <code>&lt;cstdio&gt;</code> timed 4.x seconds and 64bit versions 7.x~8.x seconds. And all versions using <code>&lt;stdio.h&gt;</code> timed around 0.4~0.6 second.</p> <p><strong>UPDATE 2</strong>: I disassembled the main function in gdb and find only one line differs: the <code>&lt;stdio.h&gt;</code> version calls <code>callq 0x4077c0 &lt;sprintf&gt;</code> but the <code>&lt;cstdio&gt;</code> version calls <code>callq 0x407990 &lt;_Z7sprintfPcPKcz&gt;</code>.</p> <p><code>sprintf</code> contains:</p> <pre><code>0x00000000004077c0 &lt;+0&gt;: jmpq *0x7c6e(%rip) # 0x40f434 &lt;__imp_sprintf&gt; 0x00000000004077c6 &lt;+6&gt;: nop 0x00000000004077c7 &lt;+7&gt;: nop </code></pre> <p>Following <code>__imp_sprintf</code> I reached the <code>sprinf</code> inside <code>msvcrt.dll</code>.</p> <p><code>_Z7sprintfPcPKcz</code> contains some mingw codes:</p> <pre><code>0x0000000000407990 &lt;+0&gt;: push %rbp 0x0000000000407991 &lt;+1&gt;: push %rbx 0x0000000000407992 &lt;+2&gt;: sub $0x38,%rsp 0x0000000000407996 &lt;+6&gt;: lea 0x80(%rsp),%rbp 0x000000000040799e &lt;+14&gt;: mov %rcx,-0x30(%rbp) 0x00000000004079a2 &lt;+18&gt;: mov %r8,-0x20(%rbp) 0x00000000004079a6 &lt;+22&gt;: mov %r9,-0x18(%rbp) 0x00000000004079aa &lt;+26&gt;: mov %rdx,-0x28(%rbp) 0x00000000004079ae &lt;+30&gt;: lea -0x20(%rbp),%rax 0x00000000004079b2 &lt;+34&gt;: mov %rax,-0x58(%rbp) 0x00000000004079b6 &lt;+38&gt;: mov -0x58(%rbp),%rdx 0x00000000004079ba &lt;+42&gt;: mov -0x28(%rbp),%rax 0x00000000004079be &lt;+46&gt;: mov %rdx,%r8 0x00000000004079c1 &lt;+49&gt;: mov %rax,%rdx 0x00000000004079c4 &lt;+52&gt;: mov -0x30(%rbp),%rcx 0x00000000004079c8 &lt;+56&gt;: callq 0x402c40 &lt;__mingw_vsprintf&gt; 0x00000000004079cd &lt;+61&gt;: mov %eax,%ebx 0x00000000004079cf &lt;+63&gt;: mov %ebx,%eax 0x00000000004079d1 &lt;+65&gt;: add $0x38,%rsp 0x00000000004079d5 &lt;+69&gt;: pop %rbx 0x00000000004079d6 &lt;+70&gt;: pop %rbp </code></pre> <p>Why does <code>cstdio</code> use a different (and much slower) function?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload