C++ wolniejszy?

0

Cześć,

tak przeglądam sobie forum i przeglądam i natknąłem się już parokrotnie na ciekawe wątki dotyczące zastosowania C++ w aplikacjach biznesowych/użytkowych. Wielokrotnie pisano, że program napisany w C++ w takich aplikacjach jest wolniejszy od programu napisanego np w Javie czy C#. Zacząłem się zastanawiać jak to możliwie, że program kompilowany do natywnego kodu może być wolniejszy od programu zarządzanego przez JVM czy .NET, które to są przecież dodatkową warstwą w komunikacji z procesorem.

Podawano wielokrotnie przykład GG jako powolnego programu ale czy to nie czasami wina programistów i dokładanych do programu bezsensownych ficzerów?

To, że w C++ pisze się dłużej np. z uwagi na ubogie biblioteki czy uboższą kontrolę typów to ok i tutaj się zgodzę, ale tak samo dobrze napisana aplikacja chyba powinna być szybsza a natywnym kodzie, który nie potrzebuje dodatkowej warstwy po to żeby dogadać się z procesorem?

Jak to dokładnie jest z tym naszym C++? Są jakieś benchmarki większych projektów aniżeli tylko pojedynczych algorytmów?

Pozdrawiam
Grzesiek

0

Słowa "ubogi" i "C++" nigdy nie powinny znajdować się w pobliżu. C++ jest potężniejszy od Javy, czy C# jeżeli chodzi o unikanie błędów czasu wykonania. Jest tylko jeden warunek, trzeba go bardzo dobrze znać (i ten warunek spełnia względnie niewielka ilość programistów). Z bibliotekami jest podobnie. Co do szybkości, jest to po części prawda, w dużym uproszczeniu jest to tak jak z pctami i konsolami i grami na nie.
Kompilator C++ musi czasami przyjąć pewne ogólne założenia (czasami kosztem optymalizacji), a JVM to taka swego rodzaju "konsola", której parametry są dokładnie znane, więc można wprowadzać daleko idące optymalizacje, które są niezależne od komputera, na którym jvm działa. Ważny jest również fakt, że wydajny kod znacznie łatwiej jest stworzyć w C# czy Javie ze względu na ich prostotę w porównaniu do C++.

3
niezalogowany napisał(a):

Słowa "ubogi" i "C++" nigdy nie powinny znajdować się w pobliżu. C++ jest potężniejszy od Javy, czy C# jeżeli chodzi o unikanie błędów czasu wykonania.

Z uwagi na konieczność ręcznego manipulowania pamięcią, można spieprzyć tyle rzeczy, że błędów jest kilkanaście razy więcej.
Z uwagi na ubóstwo intelektualną autora oraz kompatybilność z C, w C++ można robić różne popierdzielone konstrukcje, które powodują nieraz trudne do znalezienia błędy. (Np. w warunku if można użyć dowolnego typu liczbowego.)
A z uwagi na brak maszyny wirtualnej, niemożliwe są optymalizacje w locie.

Ważny jest również fakt, że wydajny kod znacznie łatwiej jest stworzyć w C# czy Javie ze względu na ich prostotę w porównaniu do C++.

A tu już sam dokopałeś leżącemu.

0

A z uwagi na brak maszyny wirtualnej, niemożliwe są optymalizacje w locie.

To jest szczegół implementacyjny, nie wymóg języka. Standard C# wymaga maszyny wirtualnej, standard C++ nic o tym nie mówi.
Przykładem C++ na maszynie wirtualnej jest C++/CLI, który jest prawie całkowicie zgodny z C++ (z wyjątkiem trzech nowych słów kluczowych).
Możesz nie użyć żadnego rozszerzenia składni, ograniczając się do C++, a program mimo to będzie działał na maszynie wirtualnej.

0

gdyby byl wolniejszy to gry (czyli tam gdzie zasoby sie najbardziej licza, [pomijam sterowniki]) byly by pisane w c# lub jave ;)

wszystko zalezy od tego do czego ma byc uzywany. Przewaznie w c#/java masz gotowe frameworki a w c++ czesto musisz to zaimplementowac sam. Tu tez bardzo czesto jest ten problem ;) nie kazdy potrafi implementowac algorytmy na poziomie frameworkow

0

A mnie się zdaje, że powolność i mułowatość programów pisanych w C++ to głównie powód błędów w implementacji, na które w C++ trzeba uważać bardziej niż w językach zarządzalnych np. ręczne zarządzanie pamięcią, wykorzystanie usuniętych (delete[]) wskaźników itd. Chociaż w tych przykładach to segfault murowany:)

0

np. ręczne zarządzanie pamięcią.

Analfabetyzm niektorych programistow jest uwazany za argument co do szybkosci jezyka, niezle. Otoz w C++ od paru ladnych lat programisci sa zwolnieni z recznego sprzatania (na czym glownie polegal problem).

1

"Inteligentne" wskaźniki to spory narzut, sprzątanie co pewien czas jak w typowych odśmiecaczach jest wielokrotnie wydajniejsze. Dlatego jeśli chce się mieć wysoką wydajność, to nie używa się "inteligentnych" wskaźników w krytycznym dla wydajności kodzie.

1

W przypadku Javy i C# nie ma żadnej "warstwy pośredniej" - kod jest kompilowany w locie do kodu maszynowego. Jedyna różnica w porównaniu z C++ jest taka, że kompilacja następuje w innym momencie. Zaleta jest taka, że kompilator ma nieco więcej informacji (np. JVM profiluje kod zanim wygeneruje kod maszynowy). Wada jest taka, że zwykle ma mniej czasu i kompiluje tylko niektóre fragmenty. Stąd w krótkożyjących aplikacjach działa to słabo.

Co do samych kompilatorów, to oczywiście są to różne kompilatory. Więc można się spodziewać różnych zestawów optymalizacji i różnej wydajności. Czasem na korzyść C++, czasem na korzyść Javy/C#. Historycznie serwerowy HotSpot Javy jest znacznie mocniejszy od kompilatorów C++ w optymalizacji wywołań wirtualnych i dynamicznych. Ponieważ aplikacje biznesowe często korzystają z takich wywołań, jak również posiadają bardzo wiele warstw abstrakcji (czasem aż za wiele), to wcale bym się nie zdziwił, że akurat taki kod wykonuje się szybciej. Podobnie w Javie alokacja dużej ilości małych obiektów na stercie jest szybsza niż podobna operacja w C++, i to nawet uwzględniając koszt sprzątania. Stąd przy masowym korzystaniu z wszelkiej maści kontenerów, znowu Java potrafi być nieco szybsza.

Co do innych optymalizacji, to znowu bywa różnie. Np. obecnie zarówno JVM jak i kompilatory C++ potrafią rozwijać i wektoryzować pętle i odnoszę wrażenie, że są w tej sztuce do siebie bardzo zbliżone. Przykład tu: http://lemire.me/blog/archives/2012/07/23/is-cc-worth-it/

I na deser do poczytania: http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain

4

@grzesiek51114 kody w C++ raczej nie są wolniejsze, ale pisze sie je znacznie dłużej niż w Javie/.NET. Fakt że JIT może optymalizować kody w interpreterach i maszynach wirtualnych sprawia jedncześnie że narzut maszyny wirtualnej może być znikomy i szybkość tych języków jest porównywalna.
Ale trzeba mieć na uwadze to że w Javie/.NET/Pythonie pisze sie znacznie szybciej niż w C/C++ i szansa na poważne błędy jest mniejsza. Jak w javie wyskoczysz poza tablicę albo zrobisz coś dziwnego to leci wyjątek, stacktrace i od razu widzisz co się stało. Jak w C/C++ coś takiego zrobisz to błąd możesz wykryć za pół roku analizując skutki uboczne w zupełnie innym module (którego mogło nie być kiedy ty pisałeś swój kod ;) ).

0
fasadin napisał(a):

gdyby byl wolniejszy to gry (czyli tam gdzie zasoby sie najbardziej licza, [pomijam sterowniki]) byly by pisane w c# lub jave ;)

Patrzac na takie silniki jak Unity3D czy Unreal Engine mozna sie zastanawiac czy gry rzeczywiscie pisane sa w C++ czy moze w jezykach typu C#, JavaScipt lub innych jezykach wymyslonych przez tworcow tego typu narzedzi.

0

Unreal Engine 3 - 250k LOC C++ wg http://www.cs.princeton.edu/~dpw/popl/06/Tim-POPL.ppt
Projekt nad którym pracuję w korpo - 3 mln LOC Java wg programu http://cloc.sourceforge.net/

Myślę, że średni poziom programistów pracujących nad UE3 jest znacznie wyższy niż średni poziom programistów pracujących u mnie w korpo i dzięki temu nie zakopują się oni w kodzie w C++.

0

A, jest jeszcze jedna istotna kwestia - dzięki temu, że w Javie/C# (a jeszcze lepiej w Scali/F#) pisze się znacznie szybciej i łatwiej, zostaje znacznie więcej czasu na optymalizowanie naprawdę istotnych fragmentów. Za wydajność w pierwszej kolejności odpowiadają algorytmy i struktury danych, a mikrooptymalizacje niskopoziomowe mają wpływ znacznie mniejszy. Lepiej poświęcić więcej czasu na dobry projekt niż na zastanawianie się nad głupotami, czy argument ma być przekazywany przez wartość, wskaźnik, const-wskaźnik, referencje, const-referencję a może smart pointer (i który).

1

Ponadto jeśli projekt jest rozwijany przez X lat, a nie wyprodukowany jednorazowo, jak np gra, to optymalizacje niskopoziomowe, a także wszelkiego rodzaju nieintuicyjne sztuczki po pierwsze drastycznie zwiększają koszt utrzymywania projektu, a po drugie (chyba w sumie ważniejsze) z czasem się degenerują, a to za sprawą tego, że ludzie którzy tworzyli dany super-zakręcony kod odchodzą, a na ich miejsce przychodzą żółtodzioby, które mają dość twarde deadline'y na implementowanie nowych funkcjonalności. Po trzecie - optymalizacje zwykle opierają się na wielu założeniach - tutaj w produkcie wydawanym jednorazowo, jak np grze, dużo łatwiej zaplanować produkt, by te założenia trzymały się rzeczywistości. W przypadku projektów rozwijanych X lat rzeczywistość, tzn wymagania projektowe się nieustannie zmieniają, a co za tym idzie stare optymalizacje tracą sens, a nawet mogą pogarszać efektywność systemu.

0

Kolejny temat w stylu C++ kontra reszta świata - brakowało mi tego. GG jest wolne nie przez wybór języka w jakim zostało napisane, jest wolne bo jest nafaszerowany pierdyliardem głupot nikomu do niczego nie potrzebnych. Są aplikacje działające szybko, które zostały napisane w C++/C#/Javie itp. Są też aplikacje działające wolno, które zostały napisane w C++/C#/Javie itp.
Wybór technologii nie wpływa na szybkość działania aplikacji (no chyba że mówimy o skrajnie dziwnych przypadkach), wpływa na szybkość skończenia projektu. Koniec, kropka.

0

Somekind, proszę czytaj na przyszłość CAŁY post, a potem komentuj fragmenty, a nie odwrotnie. W czym ja niby dokopałem leżącemu pisząc, że C# i Java są prostsze od C++ i dzięki temu można tworzyć wydajniejszy kod?

Z uwagi na konieczność ręcznego manipulowania pamięcią, można spieprzyć tyle rzeczy, że błędów jest kilkanaście razy więcej.

Fakt, zgadzam się. Ja jednak pisałem domyślnie o programiście, który zna w stopniu bardzo zaawansowanym C++. Wtedy jest on w stanie stworzyć kod bezpieczny i szybki. Co do kontrolowania zarządzania pamięcią to nie wierzę, że nigdy nie spotkałeś się z jakimkolwiek problemem jej dotyczącym w językach z GC. Widziałem już kod pisany w javie, gdzie było więcej wycieków pamięci niż w podobnym kodzie pisanym w C++.

0

I tak wycieki pamięci się zdecydowanie szybciej wykrywa w Javie niż w C++. Zrzut sterty w Javie jest łatwy i przyjemny, można sobie potem przeglądać stertę i widzimy obiekty, a nie tylko zbieraninę bajtów. W C++ można skorzystać z Valgrinda, ale to narzędzie dramatycznie spowalnia wykonywanie kodu.

0

W C++ brakuje podstawowych struktur danych dostępnych w bibliotece standardowej. Jak w Javie od ręki jest dostępne ConcurrentHashMap to w C++ (nawet w nowym standardzie) nie ma niczego takiego. Trzeba korzystać z zewnętrznych bibliotek (które są często płatne, jak TBB) lub pisać swoją implementacje.
Przez długi czas sytuacja wyglądała podobnie ze zwykłą hash mapą. W standardzie jej nie było a boosta nie zawsze można używać. Więc ludzie korzystali z dostępnej od ręki std::map (tam gdzie hash mapa była by wydajniejsza), lub nawet ze zwykłych tablic i wyszukiwania liniowego. Widziałem także własną implementacje hash mapy, która jako funkcji hashującej używała sypiącego kolizjami customu...
C++ może być wydajny o ile masz odpowiednio dużo wiedzy i czasu, żeby samemu poimplementować wydajne struktury danych, alokatory itd.
Niestety większość programistów nie ma tych dwóch rzeczy w nadmiarze.

0

Ja jednak pisałem domyślnie o programiście, który zna w stopniu bardzo zaawansowanym C++. Wtedy jest on w stanie stworzyć kod bezpieczny i szybki.

Prawie jak http://ludzie.4programmers.net/bash/?631 :D
Nie czarujmy się, to że ktoś zna dany język bardzo dobrze wcale nie znaczy ze pisze programy bez bugów. Co najwyżej nie popełnia oczywistych i ewidentnych błędów, ale te zwykle łatwo wyłapać tak czy siak. Dobry koder C++ zrobi pewnie tylko samo bugów co dobry koder Javy czy C# przy czym ten drugi błąd znajdzie relatywnie szybko.

Widziałem już kod pisany w javie, gdzie było więcej wycieków pamięci niż w podobnym kodzie pisanym w C++.

Jakieś konkrety? Bo zrobić wyciek w javie wcale nie jest tak łatwo i zwykle wynika to z wiszących wątków ;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1