Má Python budoucnost?

Re:Má Python budoucnost?
« Odpověď #435 kdy: 14. 06. 2016, 17:57:30 »
V ideálním případě žádný, protože vlákna by měla transparentně používat jen standardní knihovna, a ta bude stejně z větší části napsaná nativně. Nicméně svět ideání není a lidi eventloopy používat moc neumí...
Jak jsi tohle myslel? Eventloop mi přece sám o sobě nijak neumožňuje využít víc jader. Pokud mám v jazyce de facto jeden velký stav, který neumím rozdělit na víc nezávislých stavů, tak ty eventy stejně musím zpracovávat sekvenčně a opět využiju jenom jedno jádro. Eventloop by mohl pomoct jenom v případě, že bych uměl eventy zpracovávat paralelně, což stejně v těch zmiňovaných jazycích obvykle nejde (nebo jde za cenu hnusných hacků).

Nebo jak jsi to myslel?


Ivan Nový

Re:Má Python budoucnost?
« Odpověď #436 kdy: 14. 06. 2016, 18:55:55 »
V ideálním případě žádný, protože vlákna by měla transparentně používat jen standardní knihovna, a ta bude stejně z větší části napsaná nativně. Nicméně svět ideání není a lidi eventloopy používat moc neumí...
Jak jsi tohle myslel? Eventloop mi přece sám o sobě nijak neumožňuje využít víc jader. Pokud mám v jazyce de facto jeden velký stav, který neumím rozdělit na víc nezávislých stavů, tak ty eventy stejně musím zpracovávat sekvenčně a opět využiju jenom jedno jádro. Eventloop by mohl pomoct jenom v případě, že bych uměl eventy zpracovávat paralelně, což stejně v těch zmiňovaných jazycích obvykle nejde (nebo jde za cenu hnusných hacků).

Nebo jak jsi to myslel?

No samotný event je stav, není zaručeno pořadí událostí, takže rozdělit to lze, maximálně nějaká událost počká na dokončení nutných předchozích kroků, což principielně nebrání rozdělení výpočtu na několik jader.

gl

Re:Má Python budoucnost?
« Odpověď #437 kdy: 14. 06. 2016, 19:02:48 »
Jaká je výhoda používání skutečných vláken ve skriptovacím jazyce oproti eventloopu? Ok, skript poběží čtyřikrát rychleji na čtyřech jádrech, ale pořád používám jazyk, který je padesátkrát pomalejší než třeba ta Java.
Čtyřikrát je pořád lepší než jednou ;) A nezapomeň, že dneska má 4 jádra spíš tak možná mobil.

Ale nejde jenom o rychlost. V jazyce, který umí pořádný multithreading, ideálně green threads/processes, můžu například pro každou session od začátku až do konce nechat běžet jeden green thread a držet v něm stav té session, aniž bych ho nutně musel pořád ukládat a načítat a blokoval uživatele navzájem. Pokud tě to zajímá, můžeš se podívat, jak to dělá Phoenix v Elixiru: http://www.phoenixframework.org/docs/channels

Stav si může držet i couroutina. Koukal jsem na ten Phoenix framework. Je to pěkné, ale nevidím tam nic, k čemu by byla nutná vlákna. Ještě se na to podívám později.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #438 kdy: 14. 06. 2016, 19:23:48 »
V ideálním případě žádný, protože vlákna by měla transparentně používat jen standardní knihovna, a ta bude stejně z větší části napsaná nativně. Nicméně svět ideání není a lidi eventloopy používat moc neumí...
Jak jsi tohle myslel? Eventloop mi přece sám o sobě nijak neumožňuje využít víc jader. Pokud mám v jazyce de facto jeden velký stav, který neumím rozdělit na víc nezávislých stavů, tak ty eventy stejně musím zpracovávat sekvenčně a opět využiju jenom jedno jádro. Eventloop by mohl pomoct jenom v případě, že bych uměl eventy zpracovávat paralelně, což stejně v těch zmiňovaných jazycích obvykle nejde (nebo jde za cenu hnusných hacků).

Nebo jak jsi to myslel?
Sám o sobě ne. Nicméně o stavu jsem nic neříkal. Představuju si eventloop (kód pak je nějaká šílenost s vnořenými callbacky), přičemž volání knihovny se rozprostřou na více jader. High-level kód pak může být sekvenční a ostatní jádra využije jen kód knihovny. Záleží samozřejmě na tom, co píšu. Alternativně by šlo mít jen funkcionální datové struktury a tam, kde to nejde, na těch pár místech použít zámky. Pak by ani ten high-level kód nemusel být sekvenční.

Re:Má Python budoucnost?
« Odpověď #439 kdy: 14. 06. 2016, 19:47:25 »
Stav si může držet i couroutina. Koukal jsem na ten Phoenix framework. Je to pěkné, ale nevidím tam nic, k čemu by byla nutná vlákna. Ještě se na to podívám později.
Jde především o 1. jednoduchost řešení 2. o paralelizovatelnost "zadarmo" (bez toho, aby se o ni musel programátor nějak explicitně starat).

Načtu stránku - dojde k autentizaci a inicializaci stavu (načtení nebo vytvoření session). Každá událost na webu se pak odešle na backend (tomu procesu) a ten modifukuje stav. Zavření stránky = ztráta spojení = zrušení procesu, příp. uložení stavu.

Pokud mám green threads, můžu to celé psát tak, jako bych měl jednovláknovou aplikaci, která obsluhuje právě jednoho klienta a nic jiného ji nezajímá. Narozdíl od té výš zmíněné obezličky s N interpretery (kde jich navíc typicky nemůžu mít tolik, kolik mám klientů) ale navíc můžu snadno posílat události mezi takovými procesy. Tady v tom Phoenixu je to pubsub - klienta zajímají např. zprávy v chatové místnosti, tak každou novou zprávu odešlu na daný kanál a pubsub ji automaticky doručí všem procesům a ty procesy pak informují svého klienta. Protože těch procesů mám typicky víc než jader, škáluje mi to prakticky lineárně a přitom vůbec neřeším nějaké korutiny odskoky sem a tam, zamražení stavu a jeho zpětné načtení až na něj přijde řada, nemusím přepínat kontext jenom v pevně daných okamžicích, ale prakticky (z pohledu programátora) kdykoli atd. atd. atd.

Dost těžko se to vysvětluje, je potřeba si s tím tak půl roku hrát, aby si člověk uvědomil, v čem všem se to vyplatí a jakými všemi způsoby to usnadňuje práci. Nedělám si sebemenší naději, že bych to uměl nějak nevyvratitelně dokázat. Zkus a uvidíš, třeba se mýlím.

Nicméně o stavu jsem nic neříkal. Představuju si eventloop (kód pak je nějaká šílenost s vnořenými callbacky), přičemž volání knihovny se rozprostřou na více jader. High-level kód pak může být sekvenční a ostatní jádra využije jen kód knihovny. Záleží samozřejmě na tom, co píšu. Alternativně by šlo mít jen funkcionální datové struktury a tam, kde to nejde, na těch pár místech použít zámky. Pak by ani ten high-level kód nemusel být sekvenční.
No jo, ale takhle by to právě mohlo fungovat (jestli jsem tě pochopil správně) jenom pokud by 1. ty operace byly vůbec principielně paralelizovatelné 2. pokud by ten "podvozek" (runtime jazyka nebo knihovna) uměl poznat, že to může paralelizovat.

Jasně, pokud ten event bude "k tomuhle poli tisíce hodnot připočti jedničku", tak to paralelizovat jde. Ale to není úplně typická operace na webovém backendu, notabene napsaném v OOP jazyce, navíc tak nevyzpytatelném/flexibilním [nehodící se škrtni ;) ] jako je Python...


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #440 kdy: 14. 06. 2016, 19:58:18 »
Nicméně o stavu jsem nic neříkal. Představuju si eventloop (kód pak je nějaká šílenost s vnořenými callbacky), přičemž volání knihovny se rozprostřou na více jader. High-level kód pak může být sekvenční a ostatní jádra využije jen kód knihovny. Záleží samozřejmě na tom, co píšu. Alternativně by šlo mít jen funkcionální datové struktury a tam, kde to nejde, na těch pár místech použít zámky. Pak by ani ten high-level kód nemusel být sekvenční.
No jo, ale takhle by to právě mohlo fungovat (jestli jsem tě pochopil správně) jenom pokud by 1. ty operace byly vůbec principielně paralelizovatelné 2. pokud by ten "podvozek" (runtime jazyka nebo knihovna) uměl poznat, že to může paralelizovat.

Jasně, pokud ten event bude "k tomuhle poli tisíce hodnot připočti jedničku", tak to paralelizovat jde. Ale to není úplně typická operace na webovém backendu, notabene napsaném v OOP jazyce, navíc tak nevyzpytatelném/flexibilním [nehodící se škrtni ;) ] jako je Python...

1. Pochopitelně.
2. Chtěl jsem to nechat na programátorovi :)

Neměl jsem na mysli nic konkrétního, nicméně u webového backendu si představuju, že paralelní přístup k datům za mě ošetří databáze, takže kromě správy sessions apod. klidně můžu jednotlivé požadavky zpracovávat souběžně (ne každý na jednom vlákně, ale třeba pomocí Grand Central Dispatch). Obecně jsem pro defaultní paralelní běh s mutexy, kde jsou třeba, než sekvenční divnokód s občasnou paralelizací.

Re:Má Python budoucnost?
« Odpověď #441 kdy: 14. 06. 2016, 20:03:52 »
nicméně u webového backendu si představuju, že paralelní přístup k datům za mě ošetří databáze
No to vlastně neříkáš nic jiného, než že ten samotný obslužný kód je bezstavový - což je právě to, co platilo dřív - ten CRUD model a dneska už to nestačí/neplatí. Resp. můžeš to tak dělat, ale nebude to pohodlné a výsledky nebudou dobré (můj názor, každý nemusí souhlasit).

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #442 kdy: 14. 06. 2016, 20:10:17 »
nicméně u webového backendu si představuju, že paralelní přístup k datům za mě ošetří databáze
No to vlastně neříkáš nic jiného, než že ten samotný obslužný kód je bezstavový - což je právě to, co platilo dřív - ten CRUD model a dneska už to nestačí/neplatí. Resp. můžeš to tak dělat, ale nebude to pohodlné a výsledky nebudou dobré (můj názor, každý nemusí souhlasit).
Možná místo než databáze jsem měl říct "vrstva pro práci s daty". Chápu ale, co myslíš, a nemyslím, že si nějak oponujeme.

Re:Má Python budoucnost?
« Odpověď #443 kdy: 14. 06. 2016, 20:14:10 »
Možná místo než databáze jsem měl říct "vrstva pro práci s daty". Chápu ale, co myslíš, a nemyslím, že si nějak oponujeme.
Jasne, vsak si jenom tak povidame, nesporime se ;)

Mne se na tech green threads libi prave to, ze pokud nechces, zadnou "vrstvu pro práci s daty" tam mit nemusis - stav si proste drzis uvnitr toho vlakna, nic neresis, mas ho pro sebe a nikdo ti na nej nemuze sahat. Pohodicka, klidek ;)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #444 kdy: 14. 06. 2016, 20:43:12 »
Možná místo než databáze jsem měl říct "vrstva pro práci s daty". Chápu ale, co myslíš, a nemyslím, že si nějak oponujeme.
Jasne, vsak si jenom tak povidame, nesporime se ;)

Mne se na tech green threads libi prave to, ze pokud nechces, zadnou "vrstvu pro práci s daty" tam mit nemusis - stav si proste drzis uvnitr toho vlakna, nic neresis, mas ho pro sebe a nikdo ti na nej nemuze sahat. Pohodicka, klidek ;)
Tímhle stylem píšu taky, ale zase nedělám webové backendy, v AI si můžu hrát v blackboxu a jen vyplivnout výsledek.

gl

Re:Má Python budoucnost?
« Odpověď #445 kdy: 15. 06. 2016, 00:23:51 »
Jde především o 1. jednoduchost řešení 2. o paralelizovatelnost "zadarmo" (bez toho, aby se o ni musel programátor nějak explicitně starat).

Načtu stránku - dojde k autentizaci a inicializaci stavu (načtení nebo vytvoření session). Každá událost na webu se pak odešle na backend (tomu procesu) a ten modifukuje stav. Zavření stránky = ztráta spojení = zrušení procesu, příp. uložení stavu.

Pokud mám green threads, můžu to celé psát tak, jako bych měl jednovláknovou aplikaci, která obsluhuje právě jednoho klienta a nic jiného ji nezajímá. Narozdíl od té výš zmíněné obezličky s N interpretery (kde jich navíc typicky nemůžu mít tolik, kolik mám klientů) ale navíc můžu snadno posílat události mezi takovými procesy. Tady v tom Phoenixu je to pubsub - klienta zajímají např. zprávy v chatové místnosti, tak každou novou zprávu odešlu na daný kanál a pubsub ji automaticky doručí všem procesům a ty procesy pak informují svého klienta. Protože těch procesů mám typicky víc než jader, škáluje mi to prakticky lineárně a přitom vůbec neřeším nějaké korutiny odskoky sem a tam, zamražení stavu a jeho zpětné načtení až na něj přijde řada, nemusím přepínat kontext jenom v pevně daných okamžicích, ale prakticky (z pohledu programátora) kdykoli atd. atd. atd.

Dost těžko se to vysvětluje, je potřeba si s tím tak půl roku hrát, aby si člověk uvědomil, v čem všem se to vyplatí a jakými všemi způsoby to usnadňuje práci. Nedělám si sebemenší naději, že bych to uměl nějak nevyvratitelně dokázat. Zkus a uvidíš, třeba se mýlím.

Rozdílný asynchronní a synchronní kód se mi také nelíbí. Asynchronní kód moc často nepíšu. To, že se kontext přepíná v pevně daných okamžicích jsem vždy považoval za výhodu. Takový kód se snadno debuguje. Asi to je tím, že mám zkušenosti s vlákny jen v c/c++.

Ten koncept channelů mi přijde podobný jako v Clojure. V Clojurescriptu to funguje bez vláken.

Pro moje účely většinou stačí blokující framework. Zde http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/ jsou nějaké grafy ukazující, že při použití rychlé databáze je neblokující framework zbytečný. Websockety používám jen pro posílání notifikací ze serveru na klient. Kdybych dělal nějakou real time aplikaci typu chat, asi bych Elixir zkusil použít jako náhradu za Nodejs.

ByCzech

  • *****
  • 1 863
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #446 kdy: 15. 06. 2016, 04:42:34 »
Jako ja nevim, ale normalni Python je malokdy rychlejsi, nez Java, vetsinou i o rady pomalejsi - https://benchmarksgame.alioth.debian.org/u64q/python.html.

Tohle bych nečekal http://benchmarksgame.alioth.debian.org/u64q/php.html

Njn, když ono je to s těmi testy takové ošidné. Když bych měl parafrázovat: Nevěřím žádnému benchmarku, který jsem si sám nezfalšoval...

Kupříkladu:

C

Kód: [Vybrat]
#include <stdio.h>
 
int main ()
{
   long a;
   long sum = 0;

   for( a = 0; a < 200000000; a++ )
   {
      sum += a;
   }

   printf("sum: %ld\n", sum);
   return 0;
}

Kód: [Vybrat]
$ gcc -o bench0 bench.c && time ./bench0
sum: 19999999900000000

real    0m0.529s
user    0m0.524s
sys     0m0.000s

Půl sekundy... Hm rychlovka!

Java

Kód: [Vybrat]
class Bench {
  public static void main (String [] args)
  {
    long i, sum = 0;

    for(i=0; i<200000000; i++) {
      sum+=i;
    }
    System.out.println(sum);
  }
}

Kód: [Vybrat]
$ javac bench.java && time java Bench
19999999900000000

real    0m0.188s
user    0m0.184s
sys     0m0.016s

Tý jo! Java skoro 3x rychlejší než C?! (viz. dále)

PHP

Kód: [Vybrat]
<?php
$sum 
0;

for(
$i=0$i<200000000$i++) {
    
$sum += $i;
}

echo(
$sum."\n");
?>


Kód: [Vybrat]
$ time php -f bench.php
19999999900000000

real    0m8.860s
user    0m8.836s
sys     0m0.012s

No to se dalo čekat.

Python

Kód: [Vybrat]
sum = 0
for i in range(200000000):
    sum+=i

print(sum)

Kód: [Vybrat]
$ time python bench3.py
19999999900000000

real    0m25.327s
user    0m21.612s
sys     0m3.616s

No to teda vypadá vážně blbě!

Python 3

Kód: [Vybrat]
$ time python3 bench3.py
19999999900000000

real    0m21.746s
user    0m21.676s
sys     0m0.012s

Taky propadak! ...???

No jo, jenže...

Python 2

Kód: [Vybrat]
sum = 0
for i in xrange(200000000):
    sum+=i

print(sum)

(range vs xrange)

Kód: [Vybrat]
$ time python bench.py
19999999900000000

real    0m15.998s
user    0m15.972s
sys     0m0.000s

No vida, jedno písmenko a co to udělá, že? ;-)

A co na to JIT, když Java má, chci ho taky!

PyPy

Kód: [Vybrat]
$ time pypy bench3.py
19999999900000000

real    0m1.175s
user    0m1.152s
sys     0m0.016s

To je už hodně zajímavé, jen dvojnásobek času, který na to potřebuje C.

Kód: [Vybrat]
$ time pypy bench.py
19999999900000000

real    0m1.165s
user    0m1.156s
sys     0m0.004s

A tady jakbysmet.

Ale ruku na srdce, ono v Pythonu se to stejně má dělat jinak, že...

Python 3

Kód: [Vybrat]
print(sum(range(200000000)))

Kód: [Vybrat]
$ time python3 bench-sum-range.py
19999999900000000

real    0m3.209s
user    0m3.200s
sys     0m0.000s

To už je 7x rychlejší než původní kód...

Python 2

Kód: [Vybrat]
$ cat bench-sum-xrange.py
print sum(xrange(200000000))

Kód: [Vybrat]
$ time python bench-sum-xrange.py
19999999900000000

real    0m1.335s
user    0m1.324s
sys     0m0.000s

Tohle je dokonce 19x rychlejší než původní kód a zase se přibližujeme rychlosti Céčka.

A Python má vlastně hromady specializovaných knihoven, že...

Python 3

Kód: [Vybrat]
import numpy

print numpy.sum(numpy.arange(200000000))

Kód: [Vybrat]
$ time python3 bench-numpy.py
19999999900000000

real    0m1.745s
user    0m0.792s
sys     0m0.876s

Hm, 2x rychlejší než kód bez specializované knihovny.

Python 2

Kód: [Vybrat]
$ time python bench-numpy.py
19999999900000000

real    0m1.599s
user    0m0.684s
sys     0m0.900s

Mno a tady jsme si kupodivu nepomohli.

A pro pořádek, v Céčku bychom to asi těžko kompilovali s -O0, že?

C

Kód: [Vybrat]
$ gcc -O1 -o bench1 bench.c && time ./bench1
sum: 19999999900000000

real    0m0.085s
user    0m0.080s
sys     0m0.000s

Kde jsi Javo? :)

Kód: [Vybrat]
$ gcc -O2 -o bench2 bench.c && time ./bench2
sum: 19999999900000000

real    0m0.003s
user    0m0.000s
sys     0m0.000s

Java? Cože? Kde? :D


Pointa je myslím jasná...

  • když budu chtít, může Java vypadat lepší než C a PHP bude vypadat velmi zajímavě
  • když budu patlal, tak v Pythonu budu daleko za všemi ostatními.
  • ale pak si pustíme desktopový program v Javě a budeme se divit, co se stalo s tou pověstnou o řády rychlejší Javou
  • když budu chtít, bude se Python blížit Céčku
  • když použiji možnosti konkrétní implementace daného jazyka (specializované knihovny, JIT ap.), bude to vypadat zase úplně jinak
  • s Céčkem stejně všem nakopu zadnice, protože takhle úloha se s optimalizacemi přeloží na pár strojových instrukcí a pak je spouštění takového programu dražší než vlastní běh, ale dělat v tom backend pro webové appky bych fakt nechtěl (naposled si vzpomínám hromadu let zpátky nějaké CGI "skripy", ale to byla úplně jiná doba).

Mimochodem zkuste si ten rozsah pro jednotlivé testy zvětšit desetinásobně. Příklady s range v Python 2 vám na paměť utlučou stroj s 16 GiB RAM (protože to vytváří list o daném počtu položek), kdežto xrange či Python 3 spotřebu paměti elegatně řeší, protože to hodnoty pro výpočet generuje až když jsou třeba.

Osobně si myslím, že tvrzení, že Python je pomalý není moc moudré. Když se budeme bavit o konkrétní implementaci jazyka, to už pravda být může (CPython pro konkrétní zpatlaný algoritmus), ale nemusí (PyPy) či vhodně zvolený algoritmus a možnosti dané implementace (xrange, numpy, sum+xrange).

Docela by mohlo být zajímavé, jak by se to měnilo s výpočty ve floating point (a tady by si obdobné zadání ve FP říkalo o prohnání např. přes OpenCL ap. a pak už je jazyk irelevantní, vše to bude jen lepidlo pro HW akcelerovaný běh).
« Poslední změna: 15. 06. 2016, 04:46:55 od ByCzech »

n

Re:Má Python budoucnost?
« Odpověď #447 kdy: 15. 06. 2016, 07:25:50 »
Jako ja nevim, ale normalni Python je malokdy rychlejsi, nez Java, vetsinou i o rady pomalejsi - https://benchmarksgame.alioth.debian.org/u64q/python.html.

Tohle bych nečekal http://benchmarksgame.alioth.debian.org/u64q/php.html

Njn, když ono je to s těmi testy takové ošidné. Když bych měl parafrázovat: Nevěřím žádnému benchmarku, který jsem si sám nezfalšoval...

Kupříkladu:
....

Konecne hezky priklad pro vsechny benchmark fany. Nerikam ze je Java vyslovene spatna, taky mne z velke casti zivi, ale pokud potrebuje clovek opravdu vykon, tak se to neda s C/C++ srovnavat. A pokud ano, tak je s optimalizacema nasobne vice prace a mnohem neprehlednejsi kod, nez v C++.

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Má Python budoucnost?
« Odpověď #448 kdy: 15. 06. 2016, 07:31:25 »
Pokud vim, tak postovane benchmarky nepodvadi outsourcovanim provadeni opraci do asm/c/c++ knihoven, jako tvuj kod ;).

PS: Java snad nema specializovane matematicke knihovny? ;D

gamer

Re:Má Python budoucnost?
« Odpověď #449 kdy: 15. 06. 2016, 08:15:22 »
Njn, když ono je to s těmi testy takové ošidné. Když bych měl parafrázovat: Nevěřím žádnému benchmarku, který jsem si sám nezfalšoval...

Kupříkladu:

C

Kód: [Vybrat]
#include <stdio.h>
 
int main ()
{
   long a;
   long sum = 0;

   for( a = 0; a < 200000000; a++ )
   {
      sum += a;
   }

   printf("sum: %ld\n", sum);
   return 0;
}

Tak tenhle benchmark sis zfalšoval opravdu hezky. Viděl jsi assembler, který gcc vygeneruje?
Kód: [Vybrat]
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movabsq $19999999900000000, %rsi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    call    printf
Ten cyklus se vyhodnotí během kompilace a nic se nepočítá. Takový syntetický příklad je ale úplně k ničemu. Zkus si místo konstanty načíst horní mez cyklu ze vstupu a bude to vypadat úplně jinak.