Massiver fprintf Geschwindigkeitsunterschied ohne "-std = c99"

Ich hatte wochenlang Probleme mit einem leistungsschwachen Übersetzer, den ich geschrieben hatte. Auf dem folgenden einfachen bechmark

#include<stdio.h>

int main()
{
    int x;
    char buf[2048];
    FILE *test = fopen("test.out", "wb");
    setvbuf(test, buf, _IOFBF, sizeof buf);
    for(x=0;x<1024*1024; x++)
        fprintf(test, "%04d", x);
    fclose(test);
    return 0
}

Wir sehen das folgende Ergebnis

bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test

real    0m0.334s
user    0m0.015s
sys     0m0.016s

Wie Sie sehen, stürzt die Leistung ab, sobald das Flag "-std = c99" hinzugefügt wird:

bash-3.1$ gcc -O2 -static -std=c99 test.c -o test
bash-3.1$ time ./test

real    0m2.477s
user    0m0.015s
sys     0m0.000s

Der von mir verwendete Compiler ist gcc 4.6.2 mingw32.

Die erzeugte Datei hat eine Größe von ca. 12 MB, dies ist also ein Unterschied zwischen den beiden Größen von ca. 21 MB / s.

Laufendiff Zeigt an, dass die generierten Dateien identisch sind.

Ich nahm an, dass dies etwas mit dem Sperren von Dateien zu tun hatfprintf, von dem das Programm viel Gebrauch macht, aber ich habe in der C99-Version keinen Weg gefunden, das auszuschalten.

Ich habe es versuchtflockfile auf dem stream verwende ich am anfang des programms auch ein entsprechendesfunlockfile am Ende wurde aber mit Compiler-Fehlern über implizite Deklarationen und Linker-Fehlern begrüßt, die undefinierte Verweise auf diese Funktionen beanspruchen.

Könnte es eine andere Erklärung für dieses Problem geben, und was noch wichtiger ist, gibt es eine Möglichkeit, C99 unter Windows zu verwenden, ohne einen so enormen Leistungspreis zu zahlen?

Bearbeiten:

Nachdem Sie sich den Code angesehen haben, der mit diesen Optionen generiert wurde, sieht es in den langsamen Versionen so aus, als ob mingw Folgendes festhält:

_fprintf:
LFB0:
    .cfi_startproc
    subl    $28, %esp
    .cfi_def_cfa_offset 32
    leal    40(%esp), %eax
    movl    %eax, 8(%esp)
    movl    36(%esp), %eax
    movl    %eax, 4(%esp)
    movl    32(%esp), %eax
    movl    %eax, (%esp)
    call    ___mingw_vfprintf
    addl    $28, %esp
    .cfi_def_cfa_offset 4
    ret
    .cfi_endproc 

In der schnellen Version existiert dies einfach nicht; Ansonsten sind beide genau gleich. ich nehme an__mingw_vfprintf scheint der Slowpoke hier zu sein, aber ich habe keine Ahnung, welches Verhalten es emulieren muss, das es so langsam macht.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage