Diskuze: Rychlostní test Java vs Scala
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Funkcionalni neznamena rychlejsi. Viz rychlost kodu napsaneho v C/C++.
Téměř každý test jde napsat tak, aby něco bylo mnohonásobně pomalejší, než něco jiného.. Jen u PHP je to problém, to se něco jiného musí napsat extrémně špatně, aby PHP bylo rychlejší.
K tvému testu.. Použij v Javě STD knihovnu na to pole a uvidíš, jak to bude najednou 30x pomalejší v Javě, kvůli boxingu primitivních typů
To,, že je nějaký JAZYK pomalejší, není způsobeno tím, že má nějakou "instrukci" navíc, ale o tom, jak efektivně zachází s pamětí.. A i já jsem schopný napsat kód v C#, který spustím 3x, úplně ten samý kód nad úplně těmi samými daty a jednou potrvá 1sec, podruhé 20 a potřetí klidně zase 8sec.
Ahoj Mariane, právě proto jsem zveřejnil kódy, které testuji. Pokud dokážeš zrychlit kód napsaný ve scale, tak aby se přiblížil rychlosti javy, tak ho prosím zveřejni.
K tvému komentáři, proč bych používal v javě, něco co je mnohonásobné pomalejší při tomto testu? testuji konstrukce jazyka, což je naprostý základ, nikoliv nějaké knihovny.
Todle nemá nic společného s knihovnou, to je jen způsob, jak ukázat jednu z extrémních nevýhod javy, která má negativní dopad na její výkon a sice type erasure v generice a tudíž boxing primitivních typů.
Nevím jak zrychlit kód ve Scale, popravdě mě jazyky na bázi JVM nezajímají. Považuji to za mrtvou platformu, to je ale muj nazor a je mi jasné, že ty a David máte názor odlišný.
Psát benchmark je umění a kvůli několika chybám (které vůbec nejsou zjevné) testuješ něco trochu jiného.
Ty tvé dva kódy mi běžely daleko rychleji než tobě, scala asi 1.5x
pomalejší než java, určitě ne 20x.
Nejspíš mám jinou verzi knihoven, ale to je celkem jedno.
Zkus si pohrát s indexováním matice: matrix[i][j] = i*j
=>
matrix[j][i] = i*j
, schválně jak moc java zpomalí.
Stejně prohoď indexy i ve scale, co se stane, měl bys dostat hodně odlišná
čísla od původního testu.
To je první chyba, kdy místo rychlosti runtime omylem testuješ L2 cache.
Pro lepší test přestaň pracovat s velkými úseky paměti, pokud si nejsi
jistý, jak to funguje uvnitř.
Napiš si metodu, která bude opakovaně provádět operace nad menším polem,
např. 1kB.
Metoda by měla trvat řádově alespoň desítky milisekund, abys zase
neměřil něco jiného.
Tuhle metodu několikrát zavolej bez měření času, aby JIT dostal šanci
a pak začni měřit, kolikrát stihneš metodu provést během časového
úseku, řekněme 10 sekund.
Stejný postup udělej ve scale a závěrečné porovnání nepočítej na
čase, ale na počtu volání.
Funkcionální jazyky jsou obecně pomalejší než procedurální, to je
trade-off za vyšší abstrakci kódu.
Existují triky, jak se s tím vyrovnat, ale tvůj test je nefér k javě,
protože ve scale jsi napsal imperativní kód, ne funkcionální.
Zkus si napsat ještě třetí test, kdy napíšeš funkcionální program tak,
jak má vypadat.
Tady je to zjevně outer-product V * V', kde V je range.
Schválně, o kolik bude scala pomalejší, když v ní napíšeš čistý kus
kódu?
Tiez nie som expert v Scale ale
val result =
(1 to 10000).foreach { i1 =>
(1 to 10000).foreach { i2 =>
i1 * i2
}
}
Dobře další test je od toho prvního odlišný. Nic neukládám do proměnných, což jsem původně v javě dělal a kód se zrychlil a ani nic nevypisuji na obrazovku. Prostě dám cyklus od 1 do 200 a dané číslo pošlu do funkce, která mi vypočítá faktoriál. Nic víc, ani méně.
Scala je zase neuvěřitelně pomalá. Ty výsledky jsou ale příliš rozdílné proto ještě mrknu na verze.
java - http://www.itnetwork.cz/dev-lighter/902
scala - http://www.itnetwork.cz/dev-lighter/903
Je tohle jeden z testů, o kterém jsi mluvil.
V javě to zdržuje ta nešikovná implementace Bigintiger, ale i tak je to o dost rychlejší.
BigInteger má špatnou implementaci, takže jen měříš, jak je interně
pomalý.
Navíc v Javě pracuješ s integerem, takže alokuješ méně objektů než ve
Scale.
Když jsem to upravil, byla Java rychlejší opět asi o polovinu.
Napsat dobrý benchmark je prostě hodně těžké, ať napíšeš cokoliv, tak
se na výsledky moc nekoukej, nic ti neřeknou.
Scala je pomalejší než Java a obecně bude ještě pomalejší, protože
psát rychlý kód vyžaduje hodně zkušeností a znalostí.
V Clojure také používáme řadu nenápadných triků, které dělají
obrovský rozdíl.
Prave pozeram ine benchmarky a tiez im vacsinou vychadza java ako rychlejsia: https://benchmarksgame.alioth.debian.org/u64q/scala.html
Myslim ze pravdu ma aj @coells ze na vyuzitie scaly treba skusenosti a znalosti. Taktiez Scala je este mlady jazyk v porovnani s Javou.
Scala bude vždy pomalejší, už jen z principu funkcionálního jazyka.
Nemám se Scalou zkušenosti, ale pokud vím, tak funkcionální jazyky jsou
Immutables - to přidává nějakou režii a v porovnání s Javou, která tuto
režii nemá, to jde samozřejmě znát.
Taky předpokládám, že kompilátor Javy má větší volnost, tedy může
mnohem lépe optimalizovat, na rozdíl od funkcionálních jazyků, kde pro
optimalizaci takový prostor není.
Dovolim si oponovat s immutabilitou. Uz jen z povahy toho co rikas: pokud budu kompilovat tak immutabilitu kontroluju pri kompilaci a pak? Kde je ta rezie?
Problem je spis v tom, ze kdyz pises plne funkcionalne mas vetsi naroky na pamet, jak uz tu zaznelo.
Ta režie je až během běhu. Když odstraníš nějaký prvek ve spojáku,
tak se během běhu musí všechny jeho předci překopírovat. To stejné
platí i například pro stromy. To je režie, kterou Java nemá, dokud si ji
explicitně nenapíšeš, protože hodnoty předává referencí.
Z immutables potom plyne další důsledek - funkcionální jazyky nemají
klasické pole, protože při každé změně by se muselo celé pole
zkopírovat. Takže místo pole používá právě spoják - další degradace
výkonu, protože pro přístup k prvku je namísto konstantní složitosti
použita složitost lineární. To jsou hold všechno věci, které vychází z
logiky jazyka, kompilace s tím nemá co dělat.
No a v neposlední řadě paměť paměť paměť....když se všechno
kopíruje, někam se to musí házet. Když jsou provolávány stovky funkcí,
někam se tyto udaje musí uložit.
Nevím, s Rustem jsem nedělal, mluvím ze zkušeností s Clojurem a Lispem.
To by vysvetlovalo nasi odlisnou zkusenost. OK.
Zobrazeno 16 zpráv z 16.