Gran diferencia de velocidad de fprintf sin "-std = c99"

Había estado luchando durante semanas con un traductor de bajo rendimiento que había escrito. En el siguiente bechmark simple

#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
}

vemos el siguiente resultado

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

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

Como puede ver, en el momento en que se agrega el indicador "-std = c99", el rendimiento se derrumba:

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

El compilador que estoy usando es gcc 4.6.2 mingw32.

El archivo generado es de aproximadamente 12M, por lo que esta es una diferencia de aproximadamente 21MB / s entre los dos.

Corriendodiff Muestra que los archivos generados son idénticos.

Asumí que esto tiene algo que ver con el bloqueo de archivosfprintf, del cual el programa hace un uso intensivo, pero no he podido encontrar una manera de apagarlo en la versión C99.

Lo intentéflockfile en el flujo que utilizo al principio del programa, y ​​un correspondientefunlockfile al final, pero fue recibido con errores de compilación sobre declaraciones implícitas y errores de vinculador que afirman referencias indefinidas a esas funciones.

¿Podría haber otra explicación para este problema y, lo que es más importante, hay alguna forma de usar C99 en Windows sin pagar un precio tan alto por el rendimiento?

Editar:

Después de ver el código generado por estas opciones, parece que en las versiones lentas, mingw se pega en lo siguiente:

_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 

En la versión rápida, esto simplemente no existe; De lo contrario, ambos son exactamente iguales. Asumo__mingw_vfprintf Parece ser el lenguaje lento aquí, pero no tengo idea de qué comportamiento debe emular, lo que lo hace tan lento.

Respuestas a la pregunta(4)

Su respuesta a la pregunta