C# vs Java

0

Chciałbym się zapytać was jakie są różnice między dwoma językami c# i java? Tak, już googlowałem i nie chodzi mi o różnice w pisaniu pętli czy o system notacji ciągów tekstowych lub na jaką jest dany język użyteczny. Interesują mnie różnice między wydajnością, przeznaczeniem, zarobkami, branżą ? (kotlin vs unity), spring vs .net itp. Nie do końca też wiem jaką przewage daje wykorzystanie pointerów w c#. Napiszcie proszę cokolwiek wam przyjdzie do głowy na ten temat.

8

Interesują mnie różnice między wydajnością

Wydajnością czego? Bardzo brzydkiego niskopoziomowego kodu w stylu, którego żaden normalny programista nie używa? Wtedy można zajrzeć na https://benchmarksgame-team.pages.debian.net/benchmarksgame/
A może wydajność CRUDów i innych webowych hello worldów? Wtedy można zajrzeć na https://www.techempower.com/benchmarks/
Generalnie oba zestawienia i tak są obarczone sporym błędem. Ogólnie zarówno C# jak i Java są wystarczająco szybkie do 90%+ komercyjnych zastosowań. Mało tego, nawet JavaScript może być szybki (w typowym backendzie aplikacji webowych przede wszystkim), bo Google zainwestowało masę wysiłku w https://en.wikipedia.org/wiki/V8_(JavaScript_engine) (chociaż JS nie sprzyja zrównoleglaniu obliczeń i tutaj może kuleć).

przeznaczeniem

Obstawiam, że zarówno Java jak i C# w 90%+ to backend aplikacji webowych.

zarobkami

Od wielu lat ze statystyk wynika, że w Javie zarobki są nieco większe. Dla przykładu ze statystyk tutaj https://kodilla.com/pl/blog/ile-zarabia-programista wynika, że w Javie można zarobić jakieś 10% więcej niż w .NET. W Javie jest też znacząco więcej ofert pracy.

branżą ? (kotlin vs unity)

W Unity to podobno można co najwyżej naklepać trochę dziwacznego C#a, okrojonego do potrzeb silnika.

Branża zarówno w przypadku C# jak i Javy to (jak już napisałem) w 90%+ backend aplikacji webowych.

spring vs .net itp.

Nuda vs nuda :D a tak na serio to na szczęście nie siedzę w tym

Nie do końca też wiem jaką przewage daje wykorzystanie pointerów w c#.

Gołe wskaźniki znacząco zwiększają szansę na strzelenie sobie w stopę i osiągnięcie https://en.wikipedia.org/wiki/Memory_corruption
Wskaźniki z borrow checking, lifetimes, etc takie jak w Ruście mogą być fajne w pewnych zastosowaniach, ale gołe wskaźniki jak w C czy C# to recepta na trudne do wyśledzenia problemy i całonocne sesje z debuggerem. Nie do utrzymania, gdy terminy gonią. Zostań przy normalnym kodzie, tak jak reszta programistów.

Napiszcie proszę cokolwiek wam przyjdzie do głowy na ten temat.

Temat poruszany milion razy.

1

Wybieraj to co najpopularniejsze, miliony much nie mogą się mylić

0

Z każdym nowym wydaniem platforma .NET jest coraz szybsza:
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/

5
ple napisał(a):

Z każdym nowym wydaniem platforma .NET jest coraz szybsza:

https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/

W zasadzie to większość (nieporzuconych) platform z czasem jest coraz szybsza. Dla przykładu
https://www.phoronix.com/scan.php?page=article&item=php8-jit-june&num=2
screenshot-20210919101747.png

4

Nie bierz mojej opinii do serca, obu języków nie lubię i z żadnego na serio nie korzystam :D, ale tak w praktyce jeśli odrzucimy religijną batalię wyższość jednego języka nad drugim to zasadzie wybór opiera się na tym jakie dodatki mają dla Ciebie znaczenie.

Java

  • dobry kierunek, gdy interesuje Cię android od podszewki
  • dobry kierunek, gdy interesują Cię takie języki jak Scala, Kotlin (tzn. łatwiej jest znaleźć pracę jest z Scala/Kotlin niż F#)
  • chociaż Spring się uplasował jako domyślny framework to w Java jest (chyba, ale to pierwsza rzecz jaka mnie uderzyła gdy zaczynałem) więcej standardów i bibliotek jakie można stosować zamiennie
  • dobry kierunek jeśli bardziej odpowiada Ci Oracle / Linuks / AWS

C#

  • trochę więcej cukru składniowego, który sprawia, że piszesz mniej kodu (ale cukier to plus przy małych projektach, a im większy projekt tym wartość cukru ogrywa marginalną rolę)
  • dobry kierunek, gdy interesują Cię gry 3d
  • dobry kierunek jeśli chcesz mieć jeden i ten sam framework w każdej robocie
  • dobry kierunek jeśli bardziej Ci odpowiada MS SQL Server / Windows / Azure
4

dobry kierunek jeśli chcesz mieć jeden i ten sam framework w każdej robocie

Z tego co pisał @somekind wynika że nie koniecznie, ale ja w C-kratce nie siedzę więc nie wiem.

ale cukier to plus przy małych projektach, a im większy projekt tym wartość cukru ogrywa marginalną rolę)

A ja bym powiedział że odwrotnie. Dla przykładu - napisanie 3 razy klasy anonimowej zamiast lambdy (java < 8) nie jest męczące, a 1000 razy już jest.

1

@fgh:

dobry kierunek jeśli bardziej odpowiada Ci Oracle / Linuks / AWS
dobry kierunek jeśli bardziej Ci odpowiada MS SQL Server / Windows / Azure

A co właściwie sprawia że tak uważasz? jest jakoś trudniej z Javą na Ejzjur niż na AWS?

W ogóle jak widzę combo MS SQL Server / Windows to czuje się jakbym przeglądał 10 letnie wątki, niby to tylko taki przykład, a jednak utwardza stereotyp.

Czy może chodzi ci o to, że C# = bardziej prawdopodobne że firma jest tzw. Microsoft Shop, a zatem MS SQL?

3

W ogóle jak widzę combo MS SQL Server / Windows to czuje się jakbym przeglądał 10 letnie wątki, niby to tylko taki przykład, a jednak utwardza stereotyp.

Jeżeli w C# siedzą na MS SQL zamiast w Oracle to akurat plus dla C# ;]
A tak w pełni na na serio to i tak iększośc programistów Javovych w pracy korzysta z Windowsa zamiast Linuxa więc różnicy raczej wielkiej pod tym kontem nie ma, a .NET Core już może normalnie działać na Linuxie, więc iinuxowe serwery będą i tu i tu.

1

Jeśli pytasz o sam tylko język (dosłownie), to tutaj z całą pewnością C# zjada Javę na śniadanie. Ciekawsze by było porównywanie C# do Scali czy Kotlina, byłoby chociaż może co porównywać. A tak to porównywanie Trabanta do Ferrari

6

A tak to porównywanie Trabanta do Ferrari

To trochę bez sensu - bo nie wiadomo jakie Ferrari. Jakby chociaż wziąć Ferrari FF - to przynajmniej miejsca siedzącego jest prawie tyle co w trabancie (4 osoby).
No, chyba że z kolei weźmiemy Trabanta Kombi - wtedy Ferrari FF zjada on na śniadanie (pod względem użytkowym).
Ale z kolei Ferrari trochę lepsze ma przyspieszenie i są ludzie, którzy woleliby FF.

4
marcyse napisał(a):

Nie do końca też wiem jaką przewage daje wykorzystanie pointerów w c#.

W praktyce żadnej. Jeśli trafisz do projektu, w którym są używane, to będziesz ich używał. Ale żeby tak się stało, trzeba znaleźć firmę, która robi soft desktopowy integrujący się z jakimiś antycznymi COMami. Obstawiam, że to mniej niż procent rynku.

fgh napisał(a):
  • dobry kierunek jeśli chcesz mieć jeden i ten sam framework w każdej robocie

Do nie tego języka przypiąłeś ten punkt. To w Javie masz jeden framework - Spring, wymagany w 95% ofertach pracy, a ludzie, którzy go nie używają są postrzegani jako szczęściarze.
W dotnecie nie ma jednego standardu, więc w każdym projekcie ludzie składają sobie to wszystko, co Spring robi z różnych bibliotek.

  • dobry kierunek jeśli bardziej Ci odpowiada MS SQL Server / Windows / Azure

To mocno zależy od firmy, widziałem i Javę z MSSQL Serverm na Azurze, i dotneta z Oraclem na AWSie.

3

Znam tylko Jave, ale jakbym miał dzisiaj wybierać to nadal bym ją wybrał, gdyż:

  • oba języki dają zarobek, z tym że języki alternatywne na JVM są bardziej żywotne (Kotlin, Scala)
  • wolę Unixa / Linuksa niż Windows ze 100 różnych przyczyn
  • C# pewnie jest szybszy ale Javy nie wybieram dla szybkości, od tego jest C, Rust, C++, Fortran (OpenCL / CUDA / OpenMP itd)
  • w Javie zrobię sobie aplikację desktopową pod każdy system więc do użytku domowego też fajniejsza (można też w Lazarus, ale to język niszowy i pewnie musiałbym cały kod aplikacji w nim pisać)
  • frejmłorki - to argument głównie dla juniorów - łatwiej się nauczyć frejmłorka niż języka, ale tak samo jest w PHP, Javie czy C# - nauczysz się frejmłorka to możesz udawać że coś umiesz
  • Java w składni przypomina trochę Logo, zwłaszcza dla c-plusowca (jest tak banalnie prosta że aż przyjemna), C# za to od pierwszego dnia zaskakuje różnymi wstawkami unikalnymi dla języka - co kto lubi
9

Wydajność to nie to samo co szybkość. Szybkość w sensie czasu działania pokazywanego przez zegar na ścianie (wall-clock time) to tylko jeden z aspektów wydajności, ważny, ale nie jedyny. Javie (i .NET) udało się ten jeden aspekt względnie nieźle opanować.

Ale w wydajności mieszczą się też takie pojęcia jak:

  • ile energii wymaga wykonanie programu
  • ile pamięci program potrzebuje aby się nie wywalić w trakcie działania
  • ile pamięci potrzebuje aby osiągnął optymalny czas wykonania zadania
  • jak szybko program reaguje na zdarzenia, zwłaszcza te odebrane po raz pierwszy
  • jak szybko program się uruchamia, czy ma stabilną, przewidywalną wydajność

I niestety jeśli chodzi o te inne aspekty, to aplikacje Javowe są obiektywnie dość niewydajne.
Nie mogę się za bardzo wypowiadać o .NET, bo go w praktyce mało używałem, ale domyślam się, że jest podobnie, bo wiele poniższych cech ma wspólnych z Javą:

  • Duży narzut pamięciowy na obiekty - każdy obiekt to dodatkowy nagłówek 16 bajtów na architekturach 64-bitowych, wyjątkiem są typy proste. C# jest jednak lepszy bo ma value types (structy?) więc tu możemy trochę ten problem obejść, ale structy z tego co wiem mają dużo własnych ograniczeń i nie są zamiennikiem klas. W Javie problem ma rozwiązać projekt Valhalla, ale mówi się o nim od lat i nadal nie ma nawet bety. No i patrząc na specyfikację odczuwam mocne rozczarowanie, bo nie będzie mutowalnych structów.
  • Zarządzanie pamięcią oparte o GC - o ile można to skonfigurować tak, że będzie działać szybko (i nawet ostatnio bez większych pauz tj w końcu po 30+ latach researchu pauzy są na poziomie 1 ms), to wydajność energetyczna oraz pamięciowa jest nadal tragiczna. Mamy w firmie 3 programy do benchmarkowania napisane w Javie, każdy żre 500MB do 2 GB RAMu. Takie samo narzędzie napisane w Rust potrzebuje 16 MB RAMu (z czego 10MB na załadowanie kodu binarki), a na dodatek ma ok. 5x wyższą efektywność w sensie CPU. Ktoś powie, że 500 MB to pikuś, ale jak na jeden test odpala się 10 klientów (bo jeden nie daje rady wydajnościowo), a testów jest multum, to nagle rachunek za chmurę przychodzi dosyć nieciekawy. GC potrzebuje dużego nadmiaru pamięci aby działał efektywnie i w .NET jest podobnie. A jeśli chodzi o niskie pauzy oraz konfigurowalność GC to Java chyba jest w tej chwili state-of-the art i to .NET musi gonić.
  • Kompilacja kodu oparta o JIT - powolne uruchamianie aplikacji i do tego dodatkowe zużycie CPU na kompilację. Oczywiście jest AOT na obie platformy, ale języki takie jak Java i C# dość trudno poddają się kompilacji statycznej, bo nie były do niej projektowane. Tzn. AOT rozwiązuje problem powolnego startu i "rozgrzewania" aplikacji, natomiast odbywa się to kosztem wydajności docelowej i dlatego nie był długo stosowany. Chyba najbardziej tym Java zapewniła sobie stereotyp powolnej, bo pierwsze wrażenie liczy się najbardziej. Dodam, że na serwerach ten efekt też nie jest wcale pomijalny, bo po restarcie serwer przez jakiś czas ma mniejszą przepustowość i większe opóźnienia.
  • Leniwe i dość skomplikowane ładowanie kodu (classloading). Wszystko może działać obiektywnie szybko jak się załaduje i rozgrzeje, ale użytkownik aplikacji interaktywnej nadal będzie odczuwał lagi. Otwierasz okienko po raz pierwszy a pod spodem odpala się bardzo skomplikowana machina ładująca setki klas z dysku a w tym czasie na ekranie nic się nie dzieje.
  • Polimorfizm oparty o późne wiązanie i wywołania wirtualne - tu Java i C# są bardzo podobne. W naiwym przypadku narzut może być rzedu do 10x, ale oczywiście kompilator może ale nie musi część zoptymalizować i nie masz na to za bardzo wpływu. W praktyce nie jest to ten sam poziom co Rust/C++ gdzie masz polimorfizm oparty o wiązanie wczesne, statyczne, gwarantowane.
  • Bloat spowodowany tym, że podstawową jednostką kodu w obu platformach jest cała klasa. Nie można załadować pół klasy. Do tego klasy często mają zależności do inych klas i załadowanie jednej pociąga łańcuszek (a właściwie drzewo) ładowania - to też jest przyczyną powolnego startu oraz dużego zapotrzebowania na pamięć. W językach typu C, C++, Rust tego problemu nie ma - zasadniczo do pamięci ładuje się kod który jest wykonywany, z zaokrągleniem do wielkości strony pamięci. Zauważ, że dopóki nie wywołasz konstruktora obiektu w takim C++ to kod obiektu nie jest ładowany, a jeśli kodu klasy jest dużo, to nie zostanie załadowany cały.
3

No i patrząc na specyfikację odczuwam mocne rozczarowanie, bo nie będzie mutowalnych structów.

Ta mutowalność ma wady i zalety. W C# mutowalne structy to chyba antywzorzec. Zgugowałem na szybko "c# mutable struct" i dostałem:
https://stackoverflow.com/a/441323

First, you tend to lose changes quite easily... for example, getting things out of a list:

Foo foo = list[0];
foo.Name = "abc";

what did that change? Nothing useful...

The same with properties:

myObj.SomeProperty.Size = 22; // the compiler spots this one

forcing you to do:

Bar bar = myObj.SomeProperty;
bar.Size = 22;
myObj.SomeProperty = bar;

less critically, there is a size issue; mutable objects tend to have multiple properties; yet if you have a struct with two ints, a string, a DateTime and a bool, you can very quickly burn through a lot of memory. With a class, multiple callers can share a reference to the same instance (references are small).

Structy w Javie będą nie tylko niemutowalne, ale w ogóle pozbawione tożsamości, tzn. nie będzie się dało porównać referencji do zaboxowanych structów, nie będzie identity hash code, itp To pozwoli na usprawnienie autoboxingu, bo będzie można zdeduplikować boxy bez sprawdzania w jaki sposób program korzysta z ich referencji. W przypadku mutowalnych structów można wyczaić że referencje do zaboxowanych structów są różne, nawet jeśli structy mają taką samą zawartość. Wystarczy na chwilę coś pozmieniać używając jednej referencji i sprawdzić czy zmiana jest widoczna przez drugą. Taka semantyka zamknęłaby drogę do swobodnej deduplikacji boxów.

Ale w wydajności mieszczą się też takie pojęcia jak:

Zapomniałeś o czasie i energii poświęconej na kompilację do kodu natywnego podczas rozwoju oprogramowania. Kompilacja w trybie release jest długa. Kompilacja w trybie debug nie dość, że niekoniecznie jest szybka to prowadzi do bardzo powolnych binarek (jeśli są CPU bound). Takie miałem przynajmniej doświadczenia z Rustem kilka lat temu.

1

Skala ma problem z czasem kompilacji. Dlatego powstał Kotlin:
https://blog.jetbrains.com/kotlin/2020/09/the-dark-secrets-of-fast-compilation-for-kotlin/

Wiele firm porzuca projekty napisane w Skali ponieważ mają trudności ze znalezieniem programistów, którzy potrafiliby je utrzymać:
https://www.reddit.com/r/scala/comments/kno15t/moving_away_from_scala/
https://groups.google.com/g/scala-user/c/iI4u3Xqs5K0

3

@ple:
Trochę stary artykuł podałeś (ten dotyczący technikaliów). Kompilator Scali z wersji na wersję działa coraz szybciej. Scala 3 upraszcza składnię i mechanikę implicitów, a świeże wersje IntelliJa mają całkiem dobre wsparcie dla implicitów.

Jak ktoś chce pisać funkcyjnie to Java jest słaba. Java 8+ ma strumienie, ale i tak zostały stare kolekcje, które całkowicie nieprzystosowane do programowania funkcyjnego. Kotlin, z tego co widziałem, to też wiele tu nie zmienia, bo podstawowa hierarchia kolekcji zostaje ta sama, dla utrzymania pełnej kompatybilności z Javą (bez adapterów kolekcji). Jak ktoś chce pisać głównie imperatywnie to takiemu komuś lepiej podejdą mocno imperatywne języki jak wspomniany Kotlin.

2

Nie lepiej zwyczajnie spróbować w którym lepiej Ci się pisze, niż doszukiwać się różnic? To ma Ci sprawiać frajdę co przełoży się na późniejsze wyniki.

1

@Wibowit:

Jak ktoś chce pisać funkcyjnie to Java jest słaba. Java 8+ ma strumienie, ale i tak zostały stare kolekcje, które całkowicie nieprzystosowane do programowania funkcyjnego.

W javie do kolekcji jest vavr. Nawet jak ktoś nie pisze funkcyjnie to powinien tego (lub podobnego) pakietu używać.
java.util. kompletnie nie nadaje się do kodu domenowego. Ale to, że java się do fp nie nadaje to prawda. Po prostu ciągle ma kilka krytycznych braków, a składnia coraz bardziej męcząca (niespójna). Do tego nienaprawialne chyba decyzje (use site variance).

Kotlin, z tego co widziałem, to też wiele tu nie zmienia, bo podstawowa hierarchia kolekcji zostaje ta sama, dla utrzymania pełnej kompatybilności z Javą (bez adapterów kolekcji).

Tu się nie zgadzam. Olewamy kotlinowe kolekcje (wrapery), olewamy java.util i używamy choćby tego vavr i wychodzi całkiem spoko język funkcyjny. W sensie - w kotlinie fp ma sens.

Taka scala z systemem typów dla ubogich (ale nie jest to aż tak dramatyczny problem, dla nawracanych javowców prostota to nawet plus).
Nawet dorobiłem reguły do lintera, których nie przeszła by pewnie większość projektów w Scali https://github.com/neeffect/kure-potlin
(a ja tak staram się pisać już od 2 lat mnie więcej).

1

W każdej organizacji znajdziesz pierdyliard systemów wykonanych w różnych stackach technologicznych. Pytanie w czym się wyznajesz, co odpowiada, w czym widzisz siebie za kilka lat. Daj sobie szansę popracować w każdym z tych ekosystemów i wyciągnij wnioski dla siebie.

Mi na przykład praca z technologiami microsoftu nie leży. Tak samo nie przepadam za androidem czy adobe expecience managerem. Osobiście preferuję javę, springa, tematy devopsowe, a jak mam chwilę to daję sobie kwartał na zbudowanie jakiegoś projektu w nowym języku.

4

C# ma ładniejszą składnie oraz mądrzejszych i przystojniejszych programistów (wiem z doświadczenia).

1
Aventus napisał(a):

C# ma ładniejszą składnie oraz mądrzejszych i przystojniejszych programistów (wiem z doświadczenia).

Podbijam stawkę. Scala ma jeszcze lepszą składnię i jeszcze lepszych programistów.

1
Aventus napisał(a):

C# ma ładniejszą składnie oraz mądrzejszych i przystojniejszych programistów (wiem z doświadczenia).

Jestem programistą javy i potwierdzam

0
Wibowit napisał(a):

Podbijam stawkę. Scala ma jeszcze lepszą składnię i jeszcze lepszych programistów.

Obu?
A właściwie to nawet półtora, bo @Afish przecież w C# pisał wcześniej.

0
somekind napisał(a):

Obu?
A właściwie to nawet półtora, bo @Afish przecież w C# pisał wcześniej.

Półtora to nawet więcej niż jeden z przykładu o C#:

opieram się tylko na patrzeniu w lusterko ;) — Aventus 44 minuty temu

0

Technologii m$ nie cierpię jak komunizmu

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