On Mon, 19 Mar 2007 13:36:42 +0100 (CET), Daniele Varrazzo <[EMAIL PROTECTED]> 
wrote:

Allora, de-dissenti, questa volta :) Se non ci credi, metti 1000 url in
questa lista, e lanciala con MAX_THREAD prima a 1, poi a 10. Vedrai che c'è
differenza.

La differenza c'è perché la cosa più lenta è la rete, che nel mio caso
poteva essere sfruttata meglio. Avevo 1000 file da scaricare e mentre andava
un file alla volta vedevo col firewall personale che non facevo più di (boh,
metti) 10k/sec. Con la versione multithread ho sfruttato tutta la banda
disponibile e ho finito in una frazione del tempo (minuti anziché ore).

Manlio ha gia` risposto piu` che esaurientemente a questa domanda. Non esiste solo il multi-threading per l'IO (anzi... meglio non usare il multi-threading per i problemi di IO).

Quantomeno e` veloce uguale, in python e`
solo piu` lento.

Se eseguisse bytecode di continuo sarebbe così. Ma il collo di bottiglia è
il read, che probabilmente è una chiamata in C che rilascia il GIL.

A parte che non e` affatto detto che rilasci il GIL e infatti smtplib ha 
problemi proprio a riguardo,
resta il fatto che oltre alla read il resto e` eseguito serialmente (sostanzialmente) su un singolo processore. Il multithread quindi risulta, come detto, al massimo veloce uguale alla versione a thread
singolo che non e` solo quella seriale ma anche quella asincrona.

Secondariamente in questo caso usi un quantitativo di ram proibitivo

dov'è la ram?

Ogni thread alloca come minimo 2MB di stack se non erro (potrebbe essere molto meno). 
Piu` quello che alloca per i fatti suoi. Moltiplicato per il numero di thread che avii. 
Decisamente troppa ram buttata via per nulla (e in questo caso "ram is not 
cheap", visto che evitare di buttarla via e` ancora piu` cheap).

Quelle si appoggiano su twisted: a quelle 20 righe devi aggiungere
l'imparare twisted, che non è esattamente una passeggiata. Per te è ovvio
perché probabilmente mangi pane e twisted, ma non puoi dire che sia facile
ad una persona che sta imparando il Python ora.

Per quello nel post di risposta originario ho scritto che puo` usare anche 
pyevent o altri sistemi.
Sarebbe uno spreco di tempo a mio modo di vedere (twisted e` gia` testato e 
funzionante
anche se il client http/1.1 non e` ancora stato rilasciato, ma c'e`) ma resta 
tuttavia possibile.

Ci può essere, perché come detto è uno scriptino usa e getta che doveva fare
un lavoro una volta e finire lì. Fai bene a puntare il dito verso il
probabile bug, almeno insegni le rogne di scrivere in multithread.

Si ma andiamo piano. In questo caso la rogna non puo` essere sottovalutata. 
Infatti il tuo codice
non ha dato il minimo problema per l'uso normale, aumentando la lunghezza degli 
url da prendere
o accedendo a siti piu` veloci il risultato sarebbe stato imprevedibile (url 
non scaricati perche` poppati subito dopo essere stati aggiunti o cose simili).
Questo tipo di bachi poi sarebbe stato difficilissimo da scovare e correggere 
qual'ora quel client
fosse cresciuto in dimensioni e complessita`.

La questione e` proprio tutta li`. Immaginiamo poi di dover integrare quello 
script con quel piccolo,
ma invisibile, baco in un software piu` grosso e abbiamo una cosa assolutamente invisibile difficilissima da riprodurre (sono assolutamente certo che andando di debugger quel baco non si mostrerebbe mai ad esempio).

Non e` un problema da poco nonostante, come dici, sia un esempio giocattolo 
scritto in fretta.
Ti do sicuramente ragione, con piu` cura non ci sarebbe stato nessun problema. 
Il problema pero`
e` proprio la cura necessaria a scrivere anche un esempietto tanto semplice, 
figurarsi se e` piu`
grosso. Ecco perche` il multi-threading NON e` la risposta (quasi) MAI.

L'I/O multi-plexing si fa con sistemi asincroni (a eventi o meno) e vanno 
imparati perche` gli
altri modelli sono sbagliati e in python (in particolare) sono pure sicuramente piu` lenti (perche` comunque non sfruttano neanche il multi-core).

mi prequoto:

Spero ti serva di "ispirazione": ci ho messo pochi minuti a scriverlo, ha
fatto il suo porco lavoro

speravo fosse superfluo dire anche "non ho voglia di difendere con le unghie
e con i denti un lavoro estemporaneo fatto per superare un problema
estemporaneo ed esplicitamente proposto come tale".

Ma io non sto attando ne` te ne` il tuo lavoro. Coglievo pero` al balzo 
l'occasione che mi hai dato
mostrando quello che definivi 'semplice esempio' che pero` conteneva un baco 
definibile nella
categorie degli Heisen Bugs.

Te l'ho detto: non è stata ottimizzazione preventiva. Quello che dici tu è
vero fintantoché resti nel bytecode. Ho scritto un programma con codice
analogo che effettua interrogazioni ad un db ospitato su una macchina
multiprocessore e con un disco molto veloce. Risultato: con i thread vengono
processate 8 query contemporaneamente e il tempo totale di processo è pari
al tempo della più lenta delle query (circa 60 sec) più 1 sec, mentre prima
era la somma dei tempi. Un incremento di velocità di circa il 500%.

Come sopra: anche coi database si puo` usare l'approcio asincrono o multi 
processo a seconda
del caso. Anzi (non conosco la velocita` del driver di Manlio) tempo fa 
esisteva un driver scritto
da jamwt http://jamwt.com/ che interrogava postgres usando Twisted. Questo 
driver pure-python
era piu` veloce di psycopg2 (fondamentalmente scritto in C a MANO).

Grazie della discussione: penso sia stata più utile di come hai trattato il
povero malcapitato in precedenza. Ha sentito parlare di thread, message
passing, state sharing, lock, race condition, twisted. Ha visto differenze
di pensiero.

Anche io sono piuttosto orso il grosso delle volte, però mi sforzo di non
mangiare vive le persone solo perché ne sanno meno di me. :) Non stiamo
parlando giusto ora di organizzare un evento finalizzato a far avvicinare
persone al Python? Penso che dovremo rivolgerci positivamente ai neofiti se
vogliamo che non fuggano terrorizzati ;)

Beh ma questo non c'entra molto. Non l'ho insultato e neanche preso in giro. 
Gli ho anche scritto
quello che gli serviva per partire, come hai fatto tu, salvo che lui ha 
rifiutato di sforzarsi un pochino
cercando piu` che altro una sorta di compitino a casa fatto su quello che lui 
aveva gia` in mente.
Chiaramente pero` se leggo una persona che chiede come buttarsi giu` da un 
ponte invece che dirgli
come si fa cerco di fargli capire che ci sono altre strade per risolvere i problemi (estremizzazione esagerata per strappare un sorriso). Non e` che piglio a calci nel culo quelli che fanno domande,
in questo caso pero` mi sono sentito abbastanza ignorato nonostante le mie 
risposte che neanche
sono state lette (per giunta). Pero` quello che mi suona strano e` che mi hai 
messo nella posizione
di dovermi giustificare di un mio comportamento che non aveva nulla di male 
solo perche` si sta
organizzando pycon... Invece di giustificarmi diro`:

Un giorno un pover uomo incontra un pescatore di ritorno dalla pesca e gli chiede un pesce. Questi gli da` il pesce. Il giorno dopo la scena si ripete. Il terzo giorno la scena si ripete ancora ma questa volta il pescatore risponde: "no, io non ti daro` un pesce perche` se lo faccessi domani tornerei e ti troverei ancora qua", il pover'uomo: "ma allora io moriro` di fame", il pescatore: "non morirai di fame perche` io ti insegnero` a pescare e ti daro` la mia canna da pesca cosi` da ora in poi non avrai piu` bisogno di chiedere cibo per la mia strada".

Io penso di avergli dato la canna da pesca.
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a