Wybierz C ++ lub Java dla aplikacji wymagających dużej ilości pamięci RAM? [Zamknięte]

11

Myślę o aplikacjach naukowych, które są głównie związane z procesorem i obciążają stertę (przynajmniej kilka gigabajtów). O każdej innej porze roku chętnie skorzystałbym z C ++, ale w tym przypadku zastanawiam się, czy fragmentacja naturalna dla menedżera pamięci C ++ może stanowić poważny problem w porównaniu z zaletą kompaktorów kolektora Java.

Czy ktoś może wskazać na związane z tym rzeczywiste przykłady?

dsign
źródło
W tym przypadku nie sądzę, aby język był tak ważny jak programowanie. Każdy dojrzały język mógłby prawdopodobnie działać w zależności od skali twojego obliczenia. Istnieją języki Java, C / C ++, a nawet Pytony i Rubiny, które mogą przejść do tej roli. Niektóre byłyby trudniejsze niż inne, ponieważ brzmi to tak, jakbyś naprawdę musiał mieć pewność, że nie wycieka pamięć.
Przypon
2
Jeśli możesz dostać GB za 7,99 USD, czy to problem? Kingston 1 GB DDR3
Bo Persson
2
@BoPersson, z mojego doświadczenia, ludzie mający takie problemy zaczynają od pełnego zapełnienia swojej wysokiej klasy płyty głównej i narzekają, że nie mogą tam umieścić tyle, ile chcieliby, a następnie karmią zestaw danych tak duży, jak to możliwe, a następnie narzekają, że to nie wystarczy.
AProgrammer
@dsign, w dzisiejszych czasach, w których płyta główna akceptuje kilkaset koncertów pamięci za mniej niż 1000 €, kilka koncertów nie jest zbyt obciążonych.
AProgrammer
1
Zgadzam się z częścią taniej pamięci. Jeśli chodzi o rozwój, jestem w C ++ od jakiegoś czasu, a dobre praktyki kodowania sprawiają, że wycieki są raczej rzadkim zjawiskiem; w rzeczywistości pod tym względem wolę C ++ niż Java.
dsign

Odpowiedzi:

11

Jeśli mówisz o aplikacji, która musi obciążać granice maszyny, tak że spodziewasz się, że będziesz robił sztuczki programistyczne, aby uniknąć przekroczenia tych limitów, to C ++ jest właściwą drogą. Nie tylko C ++ daje miejsce na optymalizację tam, gdzie Java nie (jak zauważył Emilio), ale także, Garbage-Collectors są urządzeniami wymagającymi dużej ilości pamięci, które wymagają dużej ilości dodatkowej wolnej pamięci w celu wydajnej pracy.

Odpowiedzi na to pytanie: StackOverflow: Ile dodatkowej pamięci wymaga odśmiecanie ? pomaluj raczej ponury obraz, ale nawet jeśli śmieciarze potrzebują wolnej pamięci, aby być mniej więcej tyle, ile pamięci przydzielonej (co właśnie słyszałem), to nadal oznacza, że ​​w Javie nadal będziesz potrzebować dużo wolnej pamięci aby działał wydajnie.

Z drugiej strony obecnie wolimy raczej kupować droższy sprzęt niż wykonywać sztuczki programistyczne, aby uniknąć przekroczenia limitów sprzętowych. W twoim przypadku problemy z pamięcią RAM można zwykle rozwiązać za pomocą 64-bitowej maszyny i wrzucając na nią tyle modułów pamięci RAM, ile potrzeba. Widzisz, koszt sprzętu w dzisiejszym rozwiniętym świecie nie jest obecnie zbliżony do kosztu czasu programowania.

Myślę, że powinieneś poważnie rozważyć tę opcję i, jeśli to możliwe, idź z tą opcją oraz z Javą zamiast C ++, ponieważ o wiele łatwiej jest opracować coś w Javie niż w C ++ i zachować ją później.

Mike Nakis
źródło
Dziękuję za odpowiedź. Zgadzam się z twoją ilustracją sprzętu.
dsign
Jeśli nie przejmujesz się zatrzymaniem programu podczas czyszczenia pamięci, potrzeby pamięci są znacznie mniejsze.
1
Nie zgadzam się z ostatnim akapitem. Java niekoniecznie jest łatwiejsza do programowania niż C ++. To nie byłoby dla mnie, ponieważ w ciągu ostatnich pięciu lub sześciu lat napisałem dużo C ++ i stosunkowo mało Java. Możliwe jest pisanie konserwowalnego i niemożliwego do utrzymania kodu zarówno w C ++, jak i Javie.
David Thornley,
1
@DavidThornley Robiłem C / C ++ od ponad 10 lat, a Java od ponad 6 lat. Uważam, że Java jest łatwiejsza pod każdym względem: prototypowania, rozwijania, rozszerzania i utrzymywania. Ale w każdym razie tak właśnie powinny wyglądać opinie: różnią się . C -: =
Mike Nakis
Czy ktoś z was zaprogramował projekt wymagający dużych zbiorów danych i procesorów? Jakieś tam komentarze?
dsign
7

Problemem nie jest używanie C ++, ponieważ jest to Java, i nie używanie Java, ponieważ jest to C ++. Kontener C ++ jest zwykle implementowany, aby uniknąć nadmiernej fragmentacji, tak jak robią to darmowy sklep Java.

Ale jeśli przydzielisz sobie pamięć bezpośrednio, możesz także robić rzeczy, których Java na to nie pozwala, co może prowadzić do fragmentacji.

Właściwym rozwiązaniem (w C ++) jest użycie kontenera i inteligentnych wskaźników poprzez klasy alokatora, które zarządzają alokacją za pomocą stałych „pleksów” (tutaj kluczową kwestią jest napisanie dobrej klasy alokatora). Jest to styl programowania, który nie ma nic wspólnego z Javą, więc wszelkie porównania są bez znaczenia.

[EDYCJA] Może to być nieaktualna próbka: Naprawiono przydział

Emilio Garavaglia
źródło
Dziękuję za odpowiedź Emilio. Jestem w pełni świadomy elastyczności C ++ i jestem skłonny się z tobą zgodzić. Z drugiej strony chciałbym poznać kilka prawdziwych przykładów użycia, w których techniki te zostały wykorzystane do sukcesu.
dsign
@dsign: Zredagowano post, patrz link
Emilio Garavaglia
1
Użyłem tych technik wcześniej. Źle działająca aplikacja została zmieniona w swoim alokatorze, aby korzystał z zestawu hałd o stałym bloku. Więc kiedy chciałeś 4-bajtowy blok, pochodzi on ze sterty, która przechowuje tylko 4-bajtowe bloki. Jeśli chciałeś 5 bajtów, pochodziło ono z 8-bajtowej sterty bloków itp. Wzrost wydajności (w przypadku naszej aplikacji o dużej alokacji) był ogromny. Wynik może nie być tak dobry, ale może być bardzo skuteczny. Fragmentacja była zerowa, ponieważ wszystkie przydziały były w ustalonych blokach.
gbjbaanb
2

Zaletą odśmiecania jest to, że symuluje maszynę z nieskończoną ilością pamięci. Mechanizm lub implementacja tej abstrakcji ma być całkowicie przejrzysta dla ciebie jako programisty. Wszyscy wiemy, że mechanizm odzyskuje pamięć, która nie jest już używana przez program, ale nie jest to w rzeczywistości zagwarantowane. Jeśli uruchomisz program na maszynie z większą ilością pamięci RAM, niż program faktycznie używa, odebranie pamięci może nigdy nie nastąpić. Ponownie, nie ma znaczenia, ponieważ możesz po prostu napisać program bez względu na to, jak wykorzystuje pamięć. Menedżer pamięci po prostu przydzieli więcej pamięci RAM za każdym razem, gdy program tego zażąda, i możesz założyć, że takie przydzielanie zawsze się powiedzie. Java jest językiem wyrzucania elementów bezużytecznych, a C ++ nie. 1

Wadą wyrzucania elementów bezużytecznych jest to, że podobnie jak wszystkie abstrakcje , jest nieszczelny. Nie zawsze działa idealnie przez cały czas, szczególnie w skrajnych przypadkach, i prawdopodobnie napotkasz błędy. Ludzie, którzy napisali algorytm wyrzucania elementów bezużytecznych (ten, który powinien być dla ciebie przejrzysty jako programista) zoptymalizowany pod kątem najczęstszych przypadków, a problem ze zwykłymi przypadkami polega na tym, że nigdy nie są tak powszechne. Ogólnie rzecz biorąc , nie można zrobić nic lepszego niż śmieciarz w zarządzaniu pamięcią. Ale w szczególnych okolicznościach (i przy wystarczającej ilości czasu, energii i zrozumienia) może to być możliwe. C ++ zapewnia tę elastyczność; Java nie.

Wszystko to powiedziawszy, myślę, że tutaj obowiązują standardowe porady dotyczące wyboru języka, być może nawet bardziej w tym przypadku, biorąc pod uwagę ograniczenia. Wybierz język, który jest najbardziej znany głównym twórcom projektu. Oprócz oczywistych przyczyn (takich jak możliwość szybszego i bardziej wydajnego tworzenia aplikacji), jest to szczególnie ważneważne w przypadku, który opisujesz, ponieważ programowanie w C ++ tak jak programujesz w Javie spowoduje strasznie nieskuteczne praktyki zarządzania pamięcią, a zatem spowoduje wycieki i awarie. Analogicznie, programowanie w Javie, tak jak programujesz w C ++, nie przyniesie ci wiele dobrego i może skończyć się produkcją mniej niż zoptymalizowanego programu, biorąc pod uwagę, że algorytmy wyrzucania elementów bezużytecznych są modyfikowane i dostosowywane do najczęstszych przypadków .

Programiści, którzy są przyzwyczajeni do pracy w językach zbieranych przez śmieci, uczą się ufać modułowi odśmiecającemu, zamiast z nim walczyć. Jeśli pracujesz w języku zbierającym śmieci, są to programiści, których potrzebujesz w swoim projekcie. Programiści, którzy nieprzyzwyczajeni do pracy w języku zbierającym śmieci są z natury sceptyczni wobec takiej „nieskończonej pamięci” abstrakcji i często mają wiele dobrych powodów. Choć ci programiści mogą być dobrzy, nie są to osoby, które nie chcą pracować w języku zbierającym śmieci, ponieważ będą walczyć z GC na każdym kroku, nieustannie go zgadując i często wytwarzając wolniejsze, mniej wydajne pamięci kod niż inny typ programatora. W najlepszym razie po prostu spędzą dużo czasu na nowo opracowując koło, co kosztuje dużo pieniędzy, a nawet więcej w związku z długoterminowymi kosztami utrzymania.

A potem musisz również zadać sobie pytanie, czy to naprawdę ma znaczenie. W złośliwym komentarzu Bo jest coś więcej niż tylko odrobina prawdy: pamięć jest teraz tak tania, że ​​nie jest warta zbytniego wysiłku. Nawet jeśli potrzebujesz ogromnych kwot, kwoty te nie są już tak ogromne jak 10 lat temu. Programiści i tworzenie aplikacji są znacznie droższe niż kupowanie pamięci RAM i mocy obliczeniowej. Nie oznacza to, że powinieneś unikać ekonomii tam, gdzie to możliwe, ale oznacza to również, że nie powinieneś tracić zbyt wiele czasu na robienie tego.


1 Oczywiście założenie to podkreśla głębszą wadę tego pytania. Jak się okazuje, „Java lub C ++” to trochę czerwony śledź. Standardowa implementacja Java zapewnia wyrzucanie elementów bezużytecznych i C ++ nie jest zgodne ze standardem językowym, ale nie ma absolutnie żadnego powodu, dla którego nie można używać zewnętrznego modułu wyrzucania elementów bezużytecznych dla C ++. Wiele firm zarabiało na życie sprzedając te rzeczy, a niektóre zapewne zarabiały na życie, rozdając je za darmo.

Cody Gray
źródło