Massive fprintf speed difference without “-std=c99”

后端 未结 4 1077
面向向阳花
面向向阳花 2020-12-15 20:03

I had been struggling for weeks with a poor-performing translator I had written. On the following simple bechmark

#include

int main()
{
    i         


        
4条回答
  •  别那么骄傲
    2020-12-15 20:25

    After some digging in the source code, I have found why the MinGW function is so terribly slow:

    At the beginning of a [v,f,s]printf in MinGW, there is some innocent-looking initialization code:

    __pformat_t stream = {
        dest,                   /* output goes to here        */
        flags &= PFORMAT_TO_FILE | PFORMAT_NOLIMIT, /* only these valid initially */
        PFORMAT_IGNORE,             /* no field width yet         */
        PFORMAT_IGNORE,             /* nor any precision spec     */
        PFORMAT_RPINIT,             /* radix point uninitialised  */
        (wchar_t)(0),               /* leave it unspecified       */
        0,                          /* zero output char count     */
        max,                        /* establish output limit     */
        PFORMAT_MINEXP          /* exponent chars preferred   */
    };
    

    However, PFORMAT_MINEXP is not what it appears to be:

    #ifdef _WIN32
    # define PFORMAT_MINEXP    __pformat_exponent_digits() 
    # ifndef _TWO_DIGIT_EXPONENT
    #  define _get_output_format()  0 
    #  define _TWO_DIGIT_EXPONENT   1
    # endif
    static __inline__ __attribute__((__always_inline__))
    int __pformat_exponent_digits( void )
    {
      char *exponent_digits = getenv( "PRINTF_EXPONENT_DIGITS" );
      return ((exponent_digits != NULL) && ((unsigned)(*exponent_digits - '0') < 3))
        || (_get_output_format() & _TWO_DIGIT_EXPONENT)
        ? 2
        : 3
        ;
    }
    

    This winds up getting called every time I want to print, and getenv on windows must not be very quick. Replacing that define with a 2 brings the runtime back to where it should be.


    So, the answer comes down to this: when using -std=c99 or any ANSI-compliant mode, MinGW switches the CRT runtime with its own. Normally, this wouldn't be an issue, but the MinGW lib had a bug which slowed its formatting functions down far beyond anything imaginable.

提交回复
热议问题