Praca w C++? czemu programiści nie lubią C++?

0

Programowanie funkcyjne opiera się na tym, że funkcje w programie są z założenia zbliżone do funkcji matematycznych - operują tylko na danych wejściowych i wszystkie te dane traktują jak stałe. Nadal nie wiem dlaczego miałbym tutaj być zmuszony do używania ARC w C++.

0

Programowanie funkcyjne opiera się na tym, że funkcje w programie są z założenia zbliżone do funkcji matematycznych - operują tylko na danych wejściowych i wszystkie te dane traktują jak stałe.

No i to dotyczy też np funkcji na kolekcjach. Funkcja jest czysta funkcyjnie jeśli całe jej ciało jest czysto funkcyjne. Poniższa funkcja nie jest czysta funkcyjnie i wyjaśniłem to w komentarzach:

void funkcja() {
  // <- tutaj milion linii kodu funkcjnego
  puts("lol"); // <- ta linia psuje funkcyjność, bo daje efekt uboczny
  vector.push_back(5); // ta linia psuje funkcyjność tak samo jak linia powyższa
}

Nadal nie wiem dlaczego miałbym tutaj być zmuszony do używania ARC w C++.

Do trwałych struktur danych z których można korzystać z wielu wątków.

0

Jedyne co tutaj udowodniłeś, to to, że nie trzeba w C++ pisać funkcyjnie, a nie że nie można/że C++ się do tego nie nadaje.

Co do operowania na zmiennych lokalnych w funkcjach: meh, może i nie jest to za bardzo pure, ale nie łamie podstawowych założeń - funkcja jako blackbox powinna dla przyjętych parametrów zawsze zwracać to samo i nie oddziaływać z resztą wszechświata.

0

Który silnik gry (AAA) używa shared i unique pointerów?

1

Jedyne co tutaj udowodniłeś, to to, że nie trzeba w C++ pisać funkcyjnie, a nie że nie można/że C++ się do tego nie nadaje.

Co do operowania na zmiennych lokalnych w funkcjach: meh, może i nie jest to za bardzo pure, ale nie łamie podstawowych założeń - funkcja jako blackbox powinna dla przyjętych parametrów zawsze zwracać to samo i nie oddziaływać z resztą wszechświata.

Tak, czyli np jeśli funkcja przyjmuje std::vector i zwraca std::vector o nieco innej zawartości to niestety w C++ musisz skopiować te dane z wejściowego wektora które mają się znaleźć w wyjściowym. To nie jest wydajne, więc std::vector w ogólności nie nadaje się do programowania funkcyjnego. std::vector nie daje możliwości współdzielenia danych między instancjami (no chyba, że znowu zaczniesz łamać mechanizmy języka).

0

No to jest prawda, ale w praktyce, przy takim quasi-funkcyjnym podejściu funkcja otrzymuje r-referencję i może te dane spokojnie przenieść. Ale punkt dla Ciebie, jak oryginał będzie dalej w użyciu to pozostaje kopia/ARC/łamanie zasad.

0

@kq ale w firmach stosuje się te "nowoczesne" podejście do C++ ? bo coś mi się wydaje, że praca w C++ to w większości praca w legacy code.
a co sądzisz o Rust? ma szansę się wybić na rynku zdominowanym przez C/C++?
pierwsza stabilna wersja pojawiła się w 2015 roku, jednak nadal brak w tym ofert pracy... co najwyżej Rust pojawia się jako dodatkowy atut.

1
Wibowit napisał(a):

Właścicielem alokacji stała sie metoda test(), wszystkie metody wywołane wewnątrz bezpiecznie korzystają z alokacji. Func1 i func2 można by było odpalić w wątkach dodając join na nich pod koniec metody test(). Zakończenie wątków kończyło by wywołanie metody i zagwarantowało zwolnienie pamięci.
Nie ma tu zliczania referencji, zero narzutu.

Dobra. To ja opiszę schemat używania trwałych struktur danych między wątkami. W Scali używa się takiego połączenia w zasadzie jako standard. Do wielowątkowości jest Akka (która wśród Scalowców jest tak popularna jak np Spring wśród Javowców), natomiast domyślne kolekcje w Scali to właśnie trwałe struktury danych. Domyślna Lista to niemutowalna lista pojedynczo wiązana. Lista ma mniej więcej taką definicję:

trait List
case class Cons(head: T, tail: List[T]) extends List
case object Nil extends List
object List {
  def apply[T](elems: T*): List[T] = ???
}

Dołożenie elementu na początku listy odbywa się w czasie stałym (zakładając że alokacja ma złożoność liniową od ilości alokowanych bajtów). Np:

val lista234 = List(2, 3, 4) // tutaj tworzymy listę z 3 elementów + Nil
val lista1234 = Cons(1, lista234) // tutaj tworzymy listę z 4 elementów, ale przez to że ogon w całości pokrywa się z poprzednią listą to tworzenie jej jest operacją O(1)

Teraz mogę referencję lista234 wysłać do wątku Wa, referencję lista1234 wysłać do wątku Wb, wątek Wa może zrobić podobny trik z listami i ogólnie mogę tak porozsyłać listy po 10 wątkach i te listy będą współdzielić dane.

Analogicznie to trwałych list działają np standardowe mapy w Scali. Zmiana mapy polega na utworzeniu nowej mapy z zaaplikowanymi zmianami - do starej jest oczywiście cały czas normalny dostęp. Dodanie elementu do mapy tworzy więc nową mapę i ma złożoność O(lg n), bo tylko jedna ścieżka w zrównoważonym drzewie się zmienia. Reszta poddrzew jest taka sam jak w starym drzewie (zakładając, że mapa jest oparta o drzewa), więc nie trzeba ich kopiować lub je w ogóle analizować. Mapy mogę oczywiście przesyłać między wątkami tak jak opisane powyżej listy.

Jak zaimplementować wydajnie coś takiego w C++?

PS:
Schemat który opisałem to standardowe wykorzystanie wielowątkowego programowania funkcyjnego. Zawsze jak jest napisane, że programowanie funkcyjne ułatwia programowanie wielowątkowe to chodzi o schematy analogiczne do opisanego przeze mnie w tym poście.

PS2:
W Javce biblioteką do programowania funkcyjnego jest np http://www.vavr.io/ - ma zestaw trwałych kolekcji i innych bajerów.

Takie rozprawki dalej nie mają sensu bo w C++ projektujesz model pamięci DO ZADANIA, to że wymyśliłeś sobie taką listę nie znaczy że w c++ stworzyłbym to samo dla danego problemu. Mało tego za wszelką cenę projektuje się aplikacje tak żeby wymiana danych miedzy wątkami była minimalna. Poza tym jeżeli takie kolejki są wąskim gardłem to kod wielowątkowy nie miałby sensu bo jeszcze niepotrzebnie dorzuca operacje na pamięci.Wielowątkowe operacje przyśpieszają kod TYLKO kiedy wydajność jest spowolniona przez procesor lub czekanie na IO.

W ten sam sposób mogę Ci wymyślić przykład który w java będzie nie do odwzorowania, np konwersja bitmapy argb do bitmapy grayscale w taki sposób żeby ilość zapisów do pamięci dla
grayscale wynosiła xy/4 bez dodatkowych obliczeń, a odczyt wynosił O(1) bez dodatkowych przekształceń, bez castów int na *byte i na odwrót tego nie zrobisz.

Ponownie powtarzam skupianie się na poszczególnych elementach języka nie ma sensu bo to że w java może i taka lista jest łatwa i przyjemna do obsługi a do tego względnie wydajna, to nie znaczy że w c++ użyłbym takiej struktury.

Próbujesz stworzyć z Java szwajcarski scyzoryk do każdego zadania. Sam programuje w obu językach w pracy android + ndk (c++), oraz java + jni i do poszczególnych zadań używam albo java albo c++ zależnie od potrzeb.

2

Z tego co widzę, większość ofert pracy oferuje już C++11 lub nowszy, więc nie jest źle.

Rust ma trochę świetnych założeń, ale nie znam go i mam za mało wiedzy żeby przewidywać przyszłość. Konkurencja na pewno by się C++ przydała, może by komisja standaryzacyjna zaczęła pracować nad istotnymi rzeczami, zamiast pierdół.

1

No to jest prawda, ale w praktyce, przy takim quasi-funkcyjnym podejściu funkcja otrzymuje r-referencję i może te dane spokojnie przenieść. Ale punkt dla Ciebie, jak oryginał będzie dalej w użyciu to pozostaje kopia/ARC/łamanie zasad.

Po to się korzysta z funkcyjnych struktur danych by móc oryginał używać tyle razy ile się chce.

Dla przykładu możemy mieć sytuację taką (aktory to abstrakcja na wątki):

  • aktor A1 ma listę wyników meczów,
  • funkcyjną strukturą danych jest zarówno lista jak i wynik meczu (który może być skomplikowaną strukturą),
  • aktorzy B1 do B5 obsługują żądania klientów o wyniki meczów dla poszczególnych zespołów
  • aktorzy Bx wysyłają do aktora A1 żądania o same nieobrobione wyniki meczów, a A1 odpowiada im listami z referencjami do wyników
  • listy te będą prawodpodobnie całkowicie nowymi obiektami, ale zawierają same referencje, więc nie musimy kopiować samych wyników meczów,
  • klienci mogą żądać tych samych wyników wielokrotnie, więc aktorzy Bx nie mogą ich usuwać
  • aktor A1 jednak zarządza listą wyników, więc może wyniki dodawać bądź usuwać (bądź zmieniać poprzez usunięcie starej wersji i dodanie nowej),
  • kopiowanie wyników meczów wysyłanych z A1 do Bx byłoby niewydajne w porównaniu do wysyłania samych referencji do nich, no chyba, że mamy ARC, które samo w sobie jest kosztowne,
  • itp itd
  • zamiast wyników meczów mogą być np opisy towarów czy inne struktury danych,
1

Takie rozprawki dalej nie mają sensu bo w C++ projektujesz model pamięci DO ZADANIA, to że wymyśliłeś sobie taką listę nie znaczy że w c++ stworzyłbym to samo dla danego problemu. Mało tego za wszelką cenę projektuje się aplikacje tak żeby wymiana danych miedzy wątkami była minimalna. Poza tym jeżeli takie kolejki są wąskim gardłem to kod wielowątkowy nie miałby sensu bo jeszcze niepotrzebnie dorzuca operacje na pamięci.Wielowątkowe operacje przyśpieszają kod TYLKO kiedy wydajność jest spowolniona przez procesor lub czekanie na IO.

Powoli dochodzimy do sedna sprawy. Minimalizowanie wymiany danych między wątkami to uciążliwa upierdliwość w C++ie. Przy użyciu tracing GC i trwałych struktur danych przesłanie 10 bajtów między wątkami trwa tyle co przesłanie 10 gigabajtów, ponieważ zawsze przesyłamy zwykłe referencje do obojętnie jak wielkiego grafu obiektów. Nie muszę też żonglować wieloma rodzajami sprytnych wskaźników, bo tracing GC wszystko załatwia (bardzo tanim kosztem w porównaniu do ARC).

2
Wibowit napisał(a):

Takie rozprawki dalej nie mają sensu bo w C++ projektujesz model pamięci DO ZADANIA, to że wymyśliłeś sobie taką listę nie znaczy że w c++ stworzyłbym to samo dla danego problemu. Mało tego za wszelką cenę projektuje się aplikacje tak żeby wymiana danych miedzy wątkami była minimalna. Poza tym jeżeli takie kolejki są wąskim gardłem to kod wielowątkowy nie miałby sensu bo jeszcze niepotrzebnie dorzuca operacje na pamięci.Wielowątkowe operacje przyśpieszają kod TYLKO kiedy wydajność jest spowolniona przez procesor lub czekanie na IO.

Powoli dochodzimy do sedna sprawy. Minimalizowanie wymiany danych między wątkami to uciążliwa upierdliwość w C++ie. Przy użyciu tracing GC i trwałych struktur danych przesłanie 10 bajtów między wątkami trwa tyle co przesłanie 10 gigabajtów, ponieważ zawsze przesyłamy zwykłe referencje do obojętnie jak wielkiego grafu obiektów. Nie muszę też żonglować wieloma rodzajami sprytnych wskaźników, bo tracing GC wszystko załatwia.

  1. Sens ciągłej wymiany danych miedzy wątkami wyklucza sens używania wątków. Wątek tworzysz żeby wykonać ciężkie operacje względnie samodzielnie i zebrać wynik końcowy.
  2. Poza tym wymiana danych między wątkami wcale nie taka wolna, chyba że chcesz wymieniać całe masy drobnych komunikatów ale tu wracamy do pkt 1.
  3. Wymianę prostych danych kolejek itp można zrobić bardzo wydajnie korzystając z CAS.
0

Sens ciągłej wymiany danych miedzy wątkami wyklucza sens używania wątków. Wątek tworzysz żeby wykonać ciężkie operacje względnie samodzielnie i zebrać wynik końcowy.

Spaczone myślenie, spowodowane ciągłym używaniem C++a :) Wiesz jak działają mechanizmy async/ await czy Future'y w .NETu czy Javie (i prawdopodobnie też Haskellu, Erlangu, itd)? Tworzysz domknięcie, przepychasz do puli wątków (konkretnie to do kolejki w tej puli), domknięcie jest odpalane na wątku który pierwszy zdejmie go z kolejki, a potem wynik jest wstawiany w atomową referencję. Przy szerokim użyciu tych mechanizmów pomiędzy wątkami są przepychane właściwie wszystkie dane w aplikacji.

0
Wibowit napisał(a):

Sens ciągłej wymiany danych miedzy wątkami wyklucza sens używania wątków. Wątek tworzysz żeby wykonać ciężkie operacje względnie samodzielnie i zebrać wynik końcowy.

Spaczone myślenie, spowodowane ciągłym używaniem C++a :) Wiesz jak działają mechanizmy async/ await czy Future'y w .NETu czy Javie (i prawdopodobnie też Haskellu, Erlangu, itd)? Tworzysz domknięcie, przepychasz do puli wątków (konkretnie to do kolejki w tej puli), domknięcie jest odpalane na wątku który pierwszy zdejmie go z kolejki, a potem wynik jest wstawiany w atomową referencję. Przy szerokim użyciu tych mechanizmów pomiędzy wątkami są przepychane właściwie wszystkie dane w aplikacji.

Zdajesz sobie sprawę że to samo w C++ można zrobić przez CAS?

0

Zdajesz sobie sprawę że to samo w C++ można zrobić przez CAS?

No, przerzucanie samych referencji do domknięć przez kolejki robi się przez CAS (albo synchronizację, albo razem w zależności od implementacji), ale same domknięcia mogą domykać się na bardzo ciężkim stanie. Referencje z domknięcia do tego ciężkiego stanu muszą działać dobrze w środowisku wielowątkowym.

2
Heniek33 napisał(a):

Który silnik gry (AAA) używa shared i unique pointerów?

Np. Unreal

0
Wibowit napisał(a):

Zdajesz sobie sprawę że to samo w C++ można zrobić przez CAS?

No, przerzucanie samych referencji do domknięć przez kolejki robi się przez CAS, ale same domknięcia mogą domykać się na bardzo ciężkim stanie. Referencje z domknięcia do tego ciężkiego stanu muszą działać dobrze w środowisku wielowątkowym.

Czyli się da też wymieniać dane w sposób wydajny jeśli trzeba, dalej jednak twierdze że jeżyk dobieramy do problemu. Mając już wybrany najlepszy język do zadania wybieramy algorytm tak żeby korzystać z mocnych stron języka, a nie słabych po to w końcu wybieram język....
Java ułatwia pisanie względnie wydajnych aplikacji bez większego wysiłku, dlatego jest bardzo lubiana w enterprise. Jednak jeżeli ktoś pisze gry typu AAA to nie weźmie Javy żeby kopać się z jej ograniczeniami tylko C/C++ żeby żyłować ile się.
Do tego GC czasami powoduje ciekawe, niedeterministyczne działanie aplikacji, np callback w formie lambdy do metody, gdzie okazuje sie ze biblioteka z tej metody robi weekreference.
Niestety 90% osób które miałem okazje odpytywać na panelach rekrutacyjnych nie wie co to weekreference i nawet wiedząc że pod spodem jest weekref nie będzie wiedziała że to problem;p

0
kq napisał(a):

W nowoczesnym C++ (czyli prawie od dekady już) nie ma żadnej potrzeby, aby wskaźników używać jako czegokolwiek innego niż obserwatorów (co zresztą pięknie pokazuje zalinkowana wyżej prelekcja Herba Suttera), cały ten cyrk z zarządzaniem pamięcią został już imo rozwiązany. Jeśli piszesz nowy kod - piszesz go bez problemów. Jak używasz starych bibliotek, to ich używasz zgodnie z ich API. W środku mogą mieć stary kod i ewentualne memleaki, ale to nie jest zadanie dla użytkownika biblioteki.

hmm... ale czy C++ w wersji 11 jest tak "komfortowy" dla programisty jak inne języki? np. java
a i co się piszę w C++ w polskich firmach? z tego co słyszałem to głównie sterowniki. i czy więcej programuje się funkcyjnie czy obiektowo?

0

a i co się piszę w C++ w polskich firmach? z tego co słyszałem to głównie sterowniki. i czy więcej programuje się funkcyjnie czy obiektowo?

Pisze się mniejsze i większe projekty, z większych to telekomunikacja a z mniejszych np. telewizja cyfrowa. To są bardziej de facto komputery (oparte na MIPS czy ARM) z wieloma rdzeniami niż coś pokorju cortex-m4.

hmm... ale czy C++ w wersji 11 jest tak "komfortowy" dla programisty jak inne języki? np. java

Ale co rozumiesz przez komfortowy, jak masz deadliny, pisany kod przez lata mniejszym z przemyśleniem niż większym itd. To w każdym języku ci się będzie źle pisać a wiele projektów tak wygląda. C++17 daje duże możliwości, dodaje jeszcze boost i qt i masz całkiem spore pole manewru.

0

Niestety 90% osób które miałem okazje odpytywać na panelach rekrutacyjnych nie wie co to weekreference i nawet wiedząc że pod spodem jest weekref nie będzie wiedziała że to problem;p

Nie przypominam sobie bym kiedykolwiek zauważył kogoś korzystającego z WeakReference w pracy. Z drugiej strony pracując w Sabre zaimplementowałem rozproszone GC, tzn coś a'la wygaszanie sesji. Gdy klient (napisany w Swingu na desktopy) rozłączył się nagle (a więc bez poprawnej sekwencji wylogowania) od serwera to serwer musi to jakoś wykryć, np pinguje klienta co jakiś czas i jeśli ten nie odpowiada dłużej niż jakiś limit to zakłada że się rozłączył. Po wykryciu utraty połączenia, obiekty na serwerze (beany EJB2) przypisane do tego klienta są usuwane z pamięci.

Java ułatwia pisanie względnie wydajnych aplikacji bez większego wysiłku, dlatego jest bardzo lubiana w enterprise. Jednak jeżeli ktoś pisze gry typu AAA to nie weźmie Javy żeby kopać się z jej ograniczeniami tylko C/C++ żeby żyłować ile się.

To raczej C++ ma ograniczenia (z punktu widzenia programisty) niż Java. Java nie jest używana w grach AAA, gdyż przede wszystkim GC ma nadal zbyt duże pauzy (no i jest dość pamięciożerny w porównaniu do ręcznego zarządzania pamięcią). Pauza np na 200 ms w grze typu Call of Duty oznaczałaby śmierć postaci i frustrację gracza. GC o niskich opóźnieniach są dopiero w fazie eksperymentalnej: http://openjdk.java.net/projects/shenandoah/ http://openjdk.java.net/projects/zgc/ Dla aplikacji webowych przestój na poziomie 200 ms jest zupełnie akceptowalny.

Czyli się da też wymieniać dane w sposób wydajny jeśli trzeba, dalej jednak twierdze że jeżyk dobieramy do problemu. Mając już wybrany najlepszy język do zadania wybieramy algorytm tak żeby korzystać z mocnych stron języka, a nie słabych po to w końcu wybieram język....

Ktoś tu zasugerował, że dzięki kolejnym bajerom C++ zacznie nadawać się do większej ilości problemów. Moim zdaniem niespecjalnie. Różnice między Javą i .NETem, a C++em dalej sprawiają, że pisanie webowych aplikacji biznesowych w C++ jest nieopłacalne. A webowe aplikacje biznesowe to dalej chyba największa kasa, jeśli chodzi o zatrudnienie programistów.

0
Wibowit napisał(a):

Ktoś tu zasugerował, że dzięki kolejnym bajerom C++ zacznie nadawać się do większej ilości problemów. Moim zdaniem niespecjalnie. Różnice między Javą i .NETem, a C++em dalej sprawiają, że pisanie webowych aplikacji biznesowych w C++ jest nieopłacalne. A webowe aplikacje biznesowe to dalej chyba największa kasa, jeśli chodzi o zatrudnienie programistów.

Tylko kto tu w ogóle chce pisać webowe aplikacje biznesowe w C++? Przecież kompletnie nie tego dotyczy ta cała dyskusja. Ludzie, którzy wybierają C++ raczej nie chcą siedzieć w Webie.

0

Dokładnie. Jak więc rozwój C++a ma wpłynąć na zwiększenie obszaru jego zastosowań? Do czego nagle zaczął się nadawać?

0

Do tego, do czego cały czas był wykorzystywany. Po prostu praca w nim może być teraz przyjemniejsza i mniej wymagająca niż 10 lat temu.

0

Uwielbiam jave bo działa i jest przenośna, ale jak widzę potem oprogramowanie w javie, które po starcie pobiera 1GB, a po 20 minutach pracy są już 2GB, które po zadziałaniu GC dają 1,9GB, to te środowisko za przeproszeniem jest tyle warte co nic. Po drodze przepakowane programy wywalają mnóstwo błędów. Fakty, nie zamykają się, ale okienka z ostrzeżeniami o nieprawidłowym działaniu tego czy tamtego to standard.

Już na stacjonarce, żeby korzystać przyzwoicie z niektórych programów potrzebowałem 16GB ramu. To dla mnie nie jest normalne. Z przyjemnością jak tylko są narzędzia konsolowe + prosty edytor to się na to przerzucam.

A co do prostoty javy w stosunku do C++ to chciałbym zauważyć, że ten co potrafi pisać w C/C++ to da sobie dobrze radę z javą, ale jak ktoś całe życie C/C++ nie zna, bo uważa że jest trudny z powodu zarządzania pamięcią, to nie zna też javy. Najlepszy przykład znajdziemy w cudownym oprogramowaniu Klient JPK. Niby java, niby powinno być prosto, a jak się nie wywali np. w trakcie aktualizacji to uznaje to za święto :).

Podsumowując. Język językiem, ale trzeba wiedzieć co z czym, żeby dobrze posługiwać się nim.

1

Uwielbiam jave bo działa i jest przenośna, ale jak widzę potem oprogramowanie w javie, które po starcie pobiera 1GB, a po 20 minutach pracy są już 2GB, które po zadziałaniu GC dają 1,9GB, to te środowisko za przeproszeniem jest tyle warte co nic.
(...)
Podsumowując. Język językiem, ale trzeba wiedzieć co z czym, żeby dobrze posługiwać się nim.

JVM rzadko oddaje raz zajętą pamięć OSowi. JVM sam zarządza własną stertą. To tak jakbyś zrobił sobie w C++ pulę 10 GB na obiekty, napchał do niej obiektów, a potem (podczas GC) je powywalał. OS dalej widzi, że masz zaalokowane 10 GB pamięci i nie obchodzi go to, że zmniejszyłeś gdzieś tam licznik obiektów do zera. Takie rzeczy wypadałoby znać :)

Już na stacjonarce, żeby korzystać przyzwoicie z niektórych programów potrzebowałem 16GB ramu. To dla mnie nie jest normalne. Z przyjemnością jak tylko są narzędzia konsolowe + prosty edytor to się na to przerzucam.

Jeśli nie stać cię na RAM to cieniutko z kasą. Javowcy zarabiają dużo, żeby stać ich było na RAM :)

0
Wibowit napisał(a):

Niestety 90% osób które miałem okazje odpytywać na panelach rekrutacyjnych nie wie co to weekreference i nawet wiedząc że pod spodem jest weekref nie będzie wiedziała że to problem;p

Nie przypominam sobie bym kiedykolwiek zauważył kogoś korzystającego z WeakReference w pracy. Z drugiej strony pracując w Sabre zaimplementowałem rozproszone GC, tzn coś a'la wygaszanie sesji. Gdy klient (napisany w Swingu na desktopy) rozłączył się nagle (a więc bez poprawnej sekwencji wylogowania) od serwera to serwer musi to jakoś wykryć, np pinguje klienta co jakiś czas i jeśli ten nie odpowiada dłużej niż jakiś limit to zakłada że się rozłączył. Po wykryciu utraty połączenia, obiekty na serwerze (beany EJB2) przypisane do tego klienta są usuwane z pamięci.

Java ułatwia pisanie względnie wydajnych aplikacji bez większego wysiłku, dlatego jest bardzo lubiana w enterprise. Jednak jeżeli ktoś pisze gry typu AAA to nie weźmie Javy żeby kopać się z jej ograniczeniami tylko C/C++ żeby żyłować ile się.

To raczej C++ ma ograniczenia (z punktu widzenia programisty) niż Java. Java nie jest używana w grach AAA, gdyż przede wszystkim GC ma nadal zbyt duże pauzy (no i jest dość pamięciożerny w porównaniu do ręcznego zarządzania pamięcią). Pauza np na 200 ms w grze typu Call of Duty oznaczałaby śmierć postaci i frustrację gracza. GC o niskich opóźnieniach są dopiero w fazie eksperymentalnej: http://openjdk.java.net/projects/shenandoah/ http://openjdk.java.net/projects/zgc/ Dla aplikacji webowych przestój na poziomie 200 ms jest zupełnie akceptowalny.

Czyli się da też wymieniać dane w sposób wydajny jeśli trzeba, dalej jednak twierdze że jeżyk dobieramy do problemu. Mając już wybrany najlepszy język do zadania wybieramy algorytm tak żeby korzystać z mocnych stron języka, a nie słabych po to w końcu wybieram język....

Ktoś tu zasugerował, że dzięki kolejnym bajerom C++ zacznie nadawać się do większej ilości problemów. Moim zdaniem niespecjalnie. Różnice między Javą i .NETem, a C++em dalej sprawiają, że pisanie webowych aplikacji biznesowych w C++ jest nieopłacalne. A webowe aplikacje biznesowe to dalej chyba największa kasa, jeśli chodzi o zatrudnienie programistów.

Ale czy ja gdziekolwiek napisałem że chce używać c++ do weba? Wręcz przeciwnie, napisałem że enterprise to głównie java właśnie ze względu na prostotę, skalowalność i fakt że webowe aplikacje zwykle mają bottle neck dotyczący dostępu do zasobów.
C++ to mogą być elementy enterprise jak np analiza obrazu, ocr, fem czyli kod którego bottle neck to memory bus, czy właśnie gry gdzie GC powoduje niedeterministyczne zachowania aplikacji.

Co do weakreference to ja korzystałem nie raz, np przy implementacji cache w aplikacji, często potrzebny jest w androidzie żeby nie mieć memory leak kontekstu, przykład
https://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html

4

Nie będę się odnosił do wszystkiego, bo trochę mi szkoda czasu na wertowanie teraz już 6 stron nie wiadomo o czym.
Porównywanie C++ z Javą można było robić 20 lat temu jak jeszcze nie było wiadomo co to takiego ta Java jest.
Dzisiaj już chyba każdy rozumie, że Java = aplikacje biznesowe, C++ = aplikacje mało-biznesowe.
Mierzenie wydajności współdzielenia pamięci między wątkami to dla mnie jakaś pomyłka.
Może nie zrozumiałem o co chodzi, ale w C++ żeby coś wydajnie przetworzyć robi się podejście shared-nothing.
Uzasadnienie: https://en.wikipedia.org/wiki/False_sharing
Wektory funkcyjne to osobny temat, który w C++ oczywiście jest do zrealizowania.
Ivan Cukic w "Functional Programming in C++" opisuje jak to zrobić (drzewo wektorów) - patrz niżej.
Web w C/C++ można traktować w kategoriach humoru, chociaż znam ludzi którzy na tym robią kasę: https://cesanta.com/
Nie wiem co miało udowodnić porównywanie dostępu "at" z dostępem klamrowym. Przecież wiadomo że jest różnica w szybkości.

Jeśli chodzi o temat wątku:
Nie chodzi o nielubienie. Java jest po prostu kilkakrotnie składniowo prostsza od C++. W C++ można zrobić łatwiej bugi wynikające z nieznajomości języka, chociaż jak wspomniano wyżej, kody w nowszych standardach są bardziej niezawodne. C++ to nie jest język dla kogoś po bootcampie kto miał być politologiem, ale mu nie wyszło i postanowił kosić kasę w korpo. Aby programować w C++ trzeba wiedzieć co się robi, albo codziennie będziesz generował kolejne bugi. Mało którego pracodawcę na to stać. Stąd popularność Javy/C# które umożliwiają zatrudnienie pracowników mniej wykwalifikowanych. I zgadzam się, pisanie w Javie jest szybsze, mniej się zmóżdżasz nad tym co Ci wypluwa kompilator (a czasem i IDE). Co do zapotrzebowania na pamięć to myślę że Java jest kilka poziomów wyżej - widziałem już systemy dławiące się na 32 GB RAM.

Prezentacja dot. niemutowalnych wektorów w C++:

0
Wibowit napisał(a):

Uwielbiam jave bo działa i jest przenośna, ale jak widzę potem oprogramowanie w javie, które po starcie pobiera 1GB, a po 20 minutach pracy są już 2GB, które po zadziałaniu GC dają 1,9GB, to te środowisko za przeproszeniem jest tyle warte co nic.
(...)
Podsumowując. Język językiem, ale trzeba wiedzieć co z czym, żeby dobrze posługiwać się nim.

JVM rzadko oddaje raz zajętą pamięć OSowi. JVM sam zarządza własną stertą. To tak jakbyś zrobił sobie w C++ pulę 10 GB na obiekty, napchał do niej obiektów, a potem (podczas GC) je powywalał. OS dalej widzi, że masz zaalokowane 10 GB pamięci i nie obchodzi go to, że zmniejszyłeś gdzieś tam licznik obiektów do zera. Takie rzeczy wypadałoby znać :)

Już na stacjonarce, żeby korzystać przyzwoicie z niektórych programów potrzebowałem 16GB ramu. To dla mnie nie jest normalne. Z przyjemnością jak tylko są narzędzia konsolowe + prosty edytor to się na to przerzucam.

Jeśli nie stać cię na RAM to cieniutko z kasą. Javowcy zarabiają dużo, żeby stać ich było na RAM :)

Nie ważne co oddaje a co nie oddaje i co trzeba znać a co nie trzeba. Liczy się efekt. W oknach jest w sumie niewiele poza tekstem i przyciskami a pamięci jak 2 windy 10.

Co do zarobków to bym się nie spierał. O ilości kasy nie świadczy ilość ramu :). Napiszę tylko, że na kasę nie narzekam. 3 cyfry bez ułamków za godzinę to podstawa :).

Jeśli chodzi o porównywanie wydajności javy do C++ to pamiętam jak na konkursach z programowania po wprowadzeniu javy ludzie psioczyli, że javie dano takie same limity czasowe jak dla C i C++.

Jak słusznie ktoś zauważył dawno temu w tym wątku - liczą się potrzeby a potem narzędzia do nich dopasowane, potem algorytmy. Systemy wbudowane z elementami javy znajdziemy, ale większość nadal pozostaje w C i C++. Java nauczyła ludzi głupoty i braku pojęcia czym jest programowanie i jego jakość. Pamiętam jak ludzie chcieli programować w javie na mikrokontrolerach 8-bitowych z 8kB pamięci i nie widzieli w tym nic dziwnego :). Owszem, istniały jakieś pseudo nakładki, ale po co to komu miało być to nikt poważny nie wiedział :). Java wmówiła wielu ludziom, że jest prosta. Efekty widać po aplikacjach na androida, która wywalają się często przy pierwszym lepszym nieobsłużonym prawidłowo elemencie. To samo w przypadku aplikacji na PC. Nie trzeba daleko szukać: przykład klient JPK, który potrafi się wywalić przy aktualizacji. Dlatego boję się wielu programów w javie, bo bardzo często są mega reklamowane jako narzędzia i się mega wywalają na wszystkim. Do wyjątków należą poważne oprogramowania poważnych firm. One działają, chociaż jak są przeładowane i wewnętrznych błędów nie brakuje. Na szczęście się z ich powodu rzadko wywalają.

Nie zrozumcie mnie źle, java jest ok, gdyby nie wmawianie wszystkim, że jest prosta, bo to pogorszyło jakość programów, bo Heniek z budki z piwem w wolnej chwili między browarami pisze programy. I za to krytykuję właśnie javę najbardziej. Ale C i C++ też łatwe nie są, a przez to, że uważane są za trudne i wymagają więcej od programisty, to bzdury napisane w podstawowych aplikacjach szybko się ujawniają.

0

przykład klient JPK, który potrafi się wywalić przy aktualizacji. Dlatego boję się wielu programów w javie

Masz jakąś traumę od tego JPK. Ja swego czasu musiałem integrować się z poziomu Javy z biblioteką DLL napisaną w Delphi i była koszmarnie zabugowana (dużo bardziej niż jakikolwiek program w Javie, który widziałem), mimo iż kodu źródłowego było mało co. Co mam z tego wywnioskować?

Wektory funkcyjne to osobny temat, który w C++ oczywiście jest do zrealizowania.
Ivan Cukic w "Functional Programming in C++" opisuje jak to zrobić (drzewo wektorów) - patrz niżej.

Wielokrotnie wspominałem o wielowątkowości. Czy te struktury można używać z wielu wątków jednocześnie? Trwałe struktury danych, których nie można używać wielowątkowo są dość mało atrakcyjne.

0
Wibowit napisał(a):

Masz jakąś traumę od tego JPK.

Też byś miał jakbyś wiedział ile kosztuje projekt, za który płacisz w podatkach, a który pokazuje tak niski poziom. To między innymi tam jest tak, że dostajesz errora (nie ostrzeżenie) za zły nr nip eu, a potem szukasz w necie przez godzine i dowiadujesz się gdzieś tam daleko, żeby nie zwracać na to uwagi, bo mimo errora i tak można wysłać. Oczywiście żaden geniusz nie wpadł na pomysł, żeby zmienić error na warning i dodać komentarz. Tylko siedzisz i szukasz i marnujesz czas.

Zauważ, że o e-deklaracjach z adobe w tle to nawet nie wspomniałem. Nie mówiąc już o innych udogodnieniach typu płatnik :). Ani o webowych rozwiązaniach takich jak np. epuap czy cudowna obsługa zusu, w której po dziś dzień nie ma komunikatu o konieczności zmiany trybu uwierzytelniania, mimo że ludzie od kilku już lat szukają o co biega, że pliki się nie wysyłają, bo nawet nie dostajesz komunikatu o błędzie :), tylko że operacja jest w toku. W kwestii oprogramowania to państwowe oprogramowanie kosztuje majątek z naszych podatków a prezentuje poziom studenta politologii.

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