Блог пользователя Giada

Автор Giada, история, 7 лет назад, По-английски

I encountered the following issue with C++14. It seems that it is much slower than C++ and C++11. Here the same code submitted with C++, C++11, C++14.

The issue is not related to I/O (so cin/cout slowness addressed here is not involved), since the program has only to read 2 integers and write 1 integer. Moreover the code doesn't use any exotic structure or library, but only vectors.

What is the cause of this issue? Is it a known problem of the compiler?

  • Проголосовать: нравится
  • +75
  • Проголосовать: не нравится

»
7 лет назад, # |
  Проголосовать: нравится +23 Проголосовать: не нравится

Yes, I also noted that on different website (https://acmp.ru, unfortunately the only alternative there is MS VS++ 2008).

I don't know what's going on here, but this is exact reason why I don't switch from C++11's compiler to C++14.

»
7 лет назад, # |
Rev. 2   Проголосовать: нравится +52 Проголосовать: не нравится

I'm using C++14 in codeforces since they added it.

After reading your blog I tested one of my codes with C++11 and the difference was huge : 3306ms vs 622ms.

Thank you for your warning, I won't use it anymore :).

By the way, What are C++14's advantages?

  • »
    »
    7 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +26 Проголосовать: не нравится

    By the way, What are C++14's advantages?

    C++14 adds mostly nothing codeforces-useful: from the top of my head, there's decltype, auto return type, generic lambdas, std::make_unique, compile-time integer sequence templates.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +23 Проголосовать: не нравится

    C++11 isn't always better either.

    Run this code in custom input using G++ 11/14:

    Results:
    G++ 11 5.1.0 = 7987 ms, 2044 KB
    G++ 14 6.2.0 = 889 ms, 1856 KB

    Thread discussing this speed difference can be found here.

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      C++14: Used: 904 ms, 1868 KB C++11: Used: 8034 ms, 2048 KB C++: Used: 8127 ms, 2056 KB So that is this situation the C++14 is bestest.

  • »
    »
    7 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +8 Проголосовать: не нравится
»
7 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

For another problem (requires large input),

¯\_(ツ)_/¯

»
7 лет назад, # |
  Проголосовать: нравится +22 Проголосовать: не нравится

halyavin, we need one more investigation.

»
7 лет назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

My solution that yesterday worked 0.7s with C++14, now works 1.6s. So I think it's just a temporary problem on server side and will be fixed soon.

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится +18 Проголосовать: не нравится

    I'm not sure this is the reason, indeed the issue was present also yesterday as you can see in this two identical submissions:

    • »
      »
      »
      7 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится

      Oh yes, In my case it's just because new tests were added to educational round problems, but old solutions were not rejudged for some reason.

      So now I agree, it seems to be some problem in G++ 6.2 optimizations.

»
7 лет назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

I think it's incorrect to say that it's caused by difference between C++14 and C++11 but rather by different g++ versions 6.2.0 and 5.1.0. C++14/11 compilation mode could be enabled in both but I don't really think it could trigger vastly different code generation (it mostly just enabling/disabling of features).

»
7 лет назад, # |
  Проголосовать: нравится -15 Проголосовать: не нравится

Remember that on Windows we work with MinGW, g++ port to Windows. And MinGW has a lot of issues, including performance issues. So i don't know any case for original g++, where the same code compiled with C++11 is much faster than code compiled with C++14. Clang and GCC compiler are very good compilers (MSVC isn't).

»
7 лет назад, # |
  Проголосовать: нравится +33 Проголосовать: не нравится

Looks like a MinGW-specific issue.

I tested this code using 3 different compilers (gcc 5.4.1, gcc 6.3.0 and clang 3.8.0) and 3 different standards for each of them (c++03, c++11 and c++14) under ubuntu 16.04. There's no performance difference between all 9 combinations.

»
7 лет назад, # |
  Проголосовать: нравится +65 Проголосовать: не нравится

So it looks like hotspot is in calling the copy constructor of std::vector in line vector<int> at_is = is;

In general this line is not very performant (depending on number of calls) because vector allocated size doesn't get reused and thus vector always calls new every time we get to this line. Also we can observe that changing vector lifetime to static and thus reusing its capacity as in the following lines:

static vector<int> at_is;
at_is = is;

Changes time on this test quite drastically, leading to ~155ms times for both G++s which seems to prove my original point.

I looked on assembly of this part for both versions of g++ in question on Compiler Explorer and it seems to result in exactly the same new + memmove calls. So apparently it may be MinGW specific issue related to memory allocation.

»
6 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

I have a different story, C++11 is slower (almost twice RT):

C++11: 342ms

C++14: 186ms

C++17: 186ms

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    here's another similar case (x 2.5 slower)

    is something wrong with containers in C++11?

    C++11: 623ms

    C++14: 264ms

    C++17: 249ms

    Submission with C++17 is fastest everytime!