Test 3 – Benchmark na podstawie zadania „Multidrink” z XX OI
… przeprowadzić kolejny test. Ogólnie jest to cały algorytm do zadania „Multidrink” z tegorocznej Olimpiady Informatycznej z I etapu. Kod znajdziecie tutaj. W oficjalnych testach zdobył max punktów, więc pozwoliłem sobie go użyć. W moich testach – podzieliłem go na 3 fazy (zob. kod w paczce):
- Wczytanie danych (scanf)
- Przetworzenie danych
- Wypisanie danych (printf)
Nie przedłużając dłużej – oto jakże przez Was upragnione wykresy :). Tym razem specjalnie aż 3! :).
Kompilator | Wczytywanie danych (scanf+std::list) [ms] | Przetwarzanie danych [ms] | printf [ms] |
Test 3.1 – dane wejściowe ~47 KiB | |||
MSVC | 7 | 9 | 0 |
GCC | 8 | 5 | 11 |
Test 3.2 – dane wejściowe ~1.15 MiB | |||
MSVC | 140 | 180 | 17 |
GCC | 147 | 99 | 281 |
Test 3.3 – dane wejściowe ~6.67 MiB | |||
MSVC | 730 | 764 | 98 |
GCC | 760 | 386 | 1612 |
Wnioski?
- Wczytywanie danych – MSVC minimalnie lepszy.
- Wypisywanie – GCC przegrywa z kretesem.
- Najbardziej miarodajna część testu, czyli przetwarzanie danych – tu MSVC jest ok. dwukrotnie wolniejsze.
Jakie wnioski można wyciągnąć?
- scanf MSVC jest ok. 1.5 wolniejszy względem GCC
- W przypadku przetwarzania danych GCC ma miażdżącą przewagę, która rośnie (ponad liniowo?) dla coraz większych danych wejściowych
- Jeśli chodzi o printf – MSVC zyskuje kolosalną przewagę nad GCC
Najbardziej miarodajną częścią tego testu jest środkowa częśc – przetwarzanie danych. Jak widać – MSVC pod tym względem nie dał rady i ustąpił GCC-owi.
Podsumowanie
Mój benchmark nie jest żadnym super-hiper-dokładnym testem możliwości w/w kompilatorów. Przedstawiłem w tym poście prościutkie testy – i jak widać – czasem lepszy jest MSVC, a czasem GCC. Jedyną częścią, która może coś konkretnego powiedzieć jest część testu 3, a dokładniej przetwarzania danych. Jak widać – GCC jest pod tym względem lepszy od swojego substytutu. Oczywiście na tej podstawie nie można jednoznacznie stwierdzić, że GCC jest świetny, a MSVC wręcz przeciwnie, jednakże po moich doświadczeniach i moich znajomych wiem, iż GCC w zdecydowanej większości przypadków generuje wydajniejszy kod. Z resztą – nie dziwi mnie to.
Wniosek? Jeżeli zależy Ci na przesadnie wielkiej wydajności i nie wiesz, który kompilator wybrać – bierz GCC. Na podstawie tego testu – ciężko wybrać, czyli decyzję pozostawiam Wam. Przy wyborze należy jednak pamiętać o tym, że kod, który skompiluje jeden kompilator drugi niekoniecznie skompiluje. Jeżeli nie chcesz później męczyć się z poprawianiem kodu, a chcesz pisać wieloplatformowo, to można pomyśleć nad GCC.
To by było chyba na tyle… Co myślicie na ten temat? Mam nadzieję, iż ten test bardzo się Wam podobał :). Zachęcam do częstszego odwiedzania bloga bądź subskrypcji i mam prośbę – jeśli ten wpis/artykuł spodobał Ci się – daj ‚lajka’ i wrzuć linka do niego na swoje ulubione forum, kanał IRC, podeślij koledze itp. To będzie dla mnie taki bodziec, iż mam dla kogo pisać takie artykuły i że warto :). Gorąco pozdrawiam! :).
Ze skryptu kompilującego:
cl /FA %file%.%ext% -o %file%_msvc
%gcc% -O2 -std=c++11 %file%.%ext% -o %file%_gcc.exe
Czyli porównywane jest GCC z -O2 oraz MSVC z /O0. Takie porównanie nie ma sensu.
Ten tekst diametralnie zmieni swoją postać, gdy włączysz optymalizacje dla kompilatora MSVC. Obecnie porównujesz kod GCC optymalizowany do kodu MSVC z WYŁĄCZONĄ optymalizacją.
Dzięki za uwagę, testy przeprowadziłem ponownie i poprawiłem wyniki na stronie 🙂
Jeszcze jedno – porównujesz jakość kontenera std:list, a nie jakość optymalizacji kodu przez kompilatory. std::list jest beznadziejny w MSVC, więc… porównujesz dwa różne kody źródłowe i w zasadzie jest to co najwyżej ‚benchmark’ kontenera std::list oraz innych użytych narzędzi. Kiedyś sporo benchmarków robiłem różnych kontenerów i std::list pod VC++ jest na tyle beznadziejny, że należy go stosować tylko i wyłącznie tam, gdzie jest konieczność ‚wstawiania’ danych w środek iterowanej listy.
Jeszcze link do jednego z przeprowadzonych testów:
http://cpp0x.pl/forum/temat/?id=4004