Rychlost Haskell vs. C++

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #30 kdy: 24. 08. 2018, 13:17:34 »
no a kde je problém?
Je to řešení, které jde proti návrhu jazyka a nejde použít na kód, který závisí na lazy vyhodnocení (což bude většina knihoven). Respektive ono se to asi vždycky přeloží, ale kód, který závisí na lazy vyhodnocení, to rozbije až v runtime. Takže musíš přemýšlet, který kód na lazy vyhodnocení závisí a který ne a doufat, žes to pochopil správně. Pokud ne, možná to spadne až v produkci. Pokud jsi s tím smířený, tak není problém.


andy

Re:Rychlost Haskell vs. C++
« Odpověď #31 kdy: 24. 08. 2018, 13:43:25 »
Nechápu. V jazyce, který je defaultně strict musíš dělat opičárny, pokud to chceš lazy. V Haskellu holt musíš dělat opičárny, pokud to chceš strict. Mně to přijde prašť jako uhoď - a default lazy je na spoustu věcí fakt pěkná záležitost (tying the knot).
Reálně obvykle řešíš problém, jestli chceš nějaký balík dat zpracovat najednou, nebo postupně. Ve strict jazyce je to přímočaré v obou případech:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_b[i++] = foo(a);
}
i = 0;
for (b : pole_b) {
    pole_c[i++] = bar(b);
}
nebo:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_c[i++] = bar(foo(a));
}
Někdy je výhodnější první varianta, jindy druhá. Musím explicitně zvolit, jakou chci, ale obě řešení jsou jasná a přímočará. Haskell je defaultně lazy a nejde to vypnout. Ano i Haskell můžu přinutit, aby lazy nebyl, ale je to narovnávák na ohýbák, ten jazyk nebyl navržený na to, aby byl strict, je pořád lazy, i když ho přinutím spočítat něco "předčasně".
No, v haskellu by to bylo něco ve stylu:
Kód: [Vybrat]
f = fmap foo . fmap bar
vs.
f = fmap (foo . bar)
jenomže - tyhle zápisy jsou ekvivalentní, optimalizátor to ví a bůhví co z něj vyleze. Ale tady žádné lazy vs. strict nevidím, tohle obojí je skládání funkcí, v Purescriptu (který je strict) se to bude chovat principiálně stejně. Problém je spíš v tom, že haskell je tak high-level, že ty pořádně nemůžeš ovlivnit, jestli se to vykoná prvním nebo druhým způsobem - bez ohledu na striktnost.

Příklad lazy kódu:
Kód: [Vybrat]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

Nebo třeba tohle: https://github.com/quchen/articles/blob/master/loeb-moeb.md

Jak to uděláš ve strict jazyce? Docela velkou opičárnou....

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #32 kdy: 24. 08. 2018, 14:11:59 »
Problém je spíš v tom, že haskell je tak high-level, že ty pořádně nemůžeš ovlivnit, jestli se to vykoná prvním nebo druhým způsobem - bez ohledu na striktnost.
V Haskellu se to vždycky vykoná lazy způsobem, to je jasně definované, pokud teda nepoužiješ různé špinavé triky, jako třeba strict pragma, abys Haskell donutil ke strict chování.

Příklad lazy kódu:
Kód: [Vybrat]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

Nebo třeba tohle: https://github.com/quchen/articles/blob/master/loeb-moeb.md

Jak to uděláš ve strict jazyce? Docela velkou opičárnou....

Hezké. Ale taky brutálně pomalé: https://chrisdone.com/posts/twitter-problem-loeb. Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.

v

Re:Rychlost Haskell vs. C++
« Odpověď #33 kdy: 24. 08. 2018, 14:24:00 »
no a kde je problém?
Je to řešení, které jde proti návrhu jazyka a nejde použít na kód, který závisí na lazy vyhodnocení (což bude většina knihoven). Respektive ono se to asi vždycky přeloží, ale kód, který závisí na lazy vyhodnocení, to rozbije až v runtime. Takže musíš přemýšlet, který kód na lazy vyhodnocení závisí a který ne a doufat, žes to pochopil správně. Pokud ne, možná to spadne až v produkci. Pokud jsi s tím smířený, tak není problém.
tak ono se to použije jenom na zvolené moduly, ne na knihovny
a problém s tím nemám, s ne/striktností jsem nikdy problém neměl

v

Re:Rychlost Haskell vs. C++
« Odpověď #34 kdy: 24. 08. 2018, 14:33:18 »
a problém s tím nemám, s ne/striktností jsem nikdy problém neměl
v tom smylu, že možná nepíšu kód, který by na to byl háklivý


BoneFlute

  • *****
  • 1 487
    • Zobrazit profil
Re:Rychlost Haskell vs. C++
« Odpověď #35 kdy: 24. 08. 2018, 14:41:00 »
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #36 kdy: 24. 08. 2018, 14:55:46 »
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.

v

Re:Rychlost Haskell vs. C++
« Odpověď #37 kdy: 24. 08. 2018, 14:58:47 »
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
ne že by to v Cčku nešlo, třeba přeložit každý soubor s jiným nastavením zarovnání dat

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #38 kdy: 24. 08. 2018, 15:02:46 »
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
ne že by to v Cčku nešlo, třeba přeložit každý soubor s jiným nastavením zarovnání dat
To je jenom špané nastavení překladače bez vazby na zdrojový kód. Pragma strict v Haskellu dělá něco mnohem horšího, mění sémantiku existujícího kódu.

BoneFlute

  • *****
  • 1 487
    • Zobrazit profil
Re:Rychlost Haskell vs. C++
« Odpověď #39 kdy: 24. 08. 2018, 15:07:35 »
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde.
V C nám nejde o strict, ale o lazy kód.
Ten jde IMHO rozbít docela snadno. Prostě si lazy načtu data a předpokládám, a když je načtu znova, tak očekávám (ten knihovní kód očekává), že se nepoužije cache. Nějaký side-effect, etc.

Viděl bych v tom stejnou opičárnou jako v Haskellu. Jen je to naopak.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #40 kdy: 24. 08. 2018, 15:07:46 »
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.

Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde.
Výhoda C - když bys potřeboval lazy, tak to neumí... Nevýhoda haskellu - když potřebuješ strict, tak na to má direktivu, ale je to narovnávák na ohýbák....

Citace
V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #41 kdy: 24. 08. 2018, 15:21:10 »
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.
Pointa je v tom, že typicky chceš strict a ne lazy. Lazy jsou pokud vím jen Haskell a Miranda, všechny novější jazyky jsou strict, jen někdy umožňují i lazy, líbí se mi třeba řešení v OCamlu.

Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů. A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...

andy

Re:Rychlost Haskell vs. C++
« Odpověď #42 kdy: 24. 08. 2018, 15:29:06 »
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.
Pointa je v tom, že typicky chceš strict a ne lazy. Lazy jsou pokud vím jen Haskell a Miranda, všechny novější jazyky jsou strict, jen někdy umožňují i lazy, líbí se mi třeba řešení v OCamlu.
No úplně typický haskellovský trik:
Kód: [Vybrat]
for_ [1..] $ \i ->
Tohle fakt strict nechceš. Ono v haskellu nemáš cykly, funguje to tam trošku reverzně, a to výše uvedené je v podstatě streaming, který nakonec používáš docela často...

Citace
Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů.
Dělal jsi to někdy? Problém lazy vs. strict je typicky jenom tehdy, pokud je nějaké větev, která se nemá vrátit, bottom. Ale to je typicky záležitost knihoven typu nějaký hodně specifický monady, různé exception handlingy a podobně. V knihovnách, které "něco dělají" (a je tam očekávatelný bottleneck) se tohle prakticky nevyskytuje.

Citace
A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...
A napíše to za 3násobný čas co já a ještě mu to bude padat. Jasně, je to vždycky trade-off. Hele já jsem se s tím, že by moje věci byly nějak brutálně závislé na výkonu CPU setkal relativně zřídka. Občas se to stane, a pak se vyplatí nějakou konkrétní část přepsat v něčem, co je prostě rychlejší, ale u drtivé většiny věcí fakt nejdeš s výkonem na krev (samozřejmě je otázka co děláš, pokud jo, tak třeba ten OCaml klidně může mít smysl).

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #43 kdy: 24. 08. 2018, 15:44:36 »
No úplně typický haskellovský trik:
Kód: [Vybrat]
for_ [1..] $ \i ->
Tohle fakt strict nechceš. Ono v haskellu nemáš cykly, funguje to tam trošku reverzně, a to výše uvedené je v podstatě streaming, který nakonec používáš docela často...
No a o tom to celé je. Protože je Haskell lazy, píše se v něm kód, který funguje jen při lazy vyhodnocení a při strict ne. Na to není nic špatného. Jenom je potřeba počítat s tím, že lazy vyhodnocení má z principu vyšší overhead. To se vědělo od začátku. Pak ale někomu začalo vadit, že je Haskell moc pomalý a přemýšlel, jak ho zrychlit. Tak třeba bychom mohli udělat Haskell trochu strict... Co na tom, že rozbijeme existující kód... Mně se Haskell líbí, ale věci jako pragma strict jdou proti jeho designové čistotě a po pravdě moc nechápu, jak někdo z Haskell komunity může takovou věc obhajovat ;). Chápu důvody vzniku, nepřenesu se ale přes fakt, že to jde proti designu a filozofii jazyka, jen kvůli řešení výkonnostních problémů.

JSH

Re:Rychlost Haskell vs. C++
« Odpověď #44 kdy: 24. 08. 2018, 16:30:59 »
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů. A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...
A když píšeš nějakou aplikaci ve striktním jazyce, používáš jenom svoje moduly, nebo i něco externího? ... Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď co? Abys ji mohl nějak zrychlit tak ji musíš kompletně nastudovat tak jak tak.

Máš pocit, že většina knihoven ve striktních jazycích je výborně napsaná a tenhle problém tam nehrozí?