Home > Enterprise >  Slow printf: why does __USE_MINGW_ANSI_STDIO=0 make it faster?
Slow printf: why does __USE_MINGW_ANSI_STDIO=0 make it faster?

Time:12-19

I wrote the code for a problem in codeforces and even though I believe I was doing it in the best time complexity it was exceeding the time limit on the 7th test case. After some testing, it seemed to me that the major amount of time was being taken by printf, which seemed odd since using printf some 3 * 10^5 times shouldn't be such a big deal. So I searched a lot and found this: https://codeforces.com/blog/entry/105687#comment-940911
Now I made the conclusion that using this line at the top of my code will make printf faster:

#define __USE_MINGW_ANSI_STDIO 0

So I ran my code with the above included and voila what was exceeding the time limit of 1s earlier now with the inclusion of just one line of code got accepted in merely 62 ms. I didn't understand most of the other stuff that was talked about in the link like MinGW implementations and all. So my question is, firstly why does it work this way? Secondly, can I/should I keep using the above line of code in all my programs on codeforces from now on?

P.S. I also found this blog: https://codeforces.com/blog/entry/47180 It was too confusing for me to grasp for the time being but maybe someone else can understand it and shed some light on the matter.

Also, here is the codeforces problem: https://codeforces.com/contest/1774/problem/C Here is my solution: https://codeforces.com/contest/1774/submission/185781891

I don't know the entire input as codeforces doesn't share it and it'd be very very big. But I know that the value inputted to the tests variable is 3, the values inputted to n[0], n[1], n[2] are 100000, 100000, 100000

Here is my code:

#define __USE_MINGW_ANSI_STDIO 0
#include <stdio.h>
#include <stdlib.h>
// #include <math.h>
// #include <string.h>

// #define lint long long int

// Function Declarations

int main(void)
{
    int tests;
    scanf("%i", &tests);
    int **answers = malloc(tests * sizeof(int*));
    int *n = malloc(sizeof(int) * tests);
    for (int i = 0; i < tests; i  )
    {
        scanf("%i", &n[i]);
        char *enviro = malloc((n[i]) * sizeof(int));
        answers[i] = malloc((n[i] - 1) * sizeof(int));
        int consec = 1; // No. of same consecutive elements at the very 
                        // end.
        scanf("%s", enviro);
        answers[i][0] = 1; // Case where x = 2;
        for (int x = 3; x < n[i]   1; x  )
        {
            // comparing corresponding to current x vs previous x
            if (enviro[x - 2] == enviro[x - 3])
            {
                consec  ;
            }
            else
            {
                 consec = 1;
            }
            answers[i][x - 2] = x - consec;
        }
        // Free loop variables
        free(enviro);
    }
    /* if (tests == 3)
    {
        printf("n[%i] = %i\n", i, n[i]);
    } */
    for (int i = 0; i < tests; i  )
    {
        for (int j = 0; j < n[i] - 1; j  )
        {
            printf("%i ", answers[i][j]);
        }
        printf("\n");
        free(answers[i]);
    }
    // Free variables
    free(answers);
    return 0;
}

EDIT: So I tried the following code for the same problem on codeforces (https://codeforces.com/contest/1774/submission/185788962) just to see the execution time:

// #define __USE_MINGW_ANSI_STDIO 0
#include <stdio.h>
#include <math.h>

int main(void)
{
    int n = pow(10, 5);
    for (int i = 0; i < n; i  )
    {
        printf("*");
    }
}

Without the #define __USE_MINGW_ANSI_STDIO 0 it gave an e.t. of 374ms. With it, it gave e.t. of 15ms.

CodePudding user response:

It seems like MinGW defined their own printf() functions, __mingw_printf(). This is done to fix format specifiers' problems on some old Windows operating systems, as seen in their wikis. The macro __USE_MINGW_ANSI_STDIO is set to 0 if you don't want to use MinGW's implementation, and 1 if you do.

It also seems like MinGW's implementation is slower, so not using it will make your code faster.

  • Related