On Jan 5, 2010, at 1:01 PM, Stefano Dal Pra wrote:

> Perche' quella e' pura e semplice sintassi python, quindi legittima.

Attenzione ad usare il termine "sintassi" a sproposito.
Tutta e' "sintassi" python, se non sarebbe rifiutata dal compilatore
e saremmo in presenza di programmi non ben formati.

> Poi per motivi di efficienza:
> l'interprete, se non e' scemo, dovrebbe tradurre il | 1 con una
> singola istruzione macchina (or bit a bit). Se  devi generare un
> dispari e via, ok. Se ne devi fare moltissimi e piu' rapidamente
> possibile, il discorso cambia.

Ho smesso nel credere alle misure spannometriche.

1. assumi che la macchina virtuale Python *sia* scema
2. in generale in Python e' l'astrazione a pagare, non il dettaglio a basso 
livello.

Quindi, se voglio dire che "una cosa e' piu' veloce di un'altra" la misuro.
Finche' non mi sono reso conto che *ho* un problema di performance, la cosa non 
la valuto neppure.
Se la valuto, la valuto in modo oggettivo, controllato, misurato. Cerco il 
collo di bottiglia
e non intervengo "a caso". Trovato il collo di bottiglia, si valuta se lo 
speedup atteso
sia comparabile con il peggioramento del codice oppure se non sia possibile un 
intervento
architetturale piu' efficiente ancora.

A questo punto si procede, misurando attentamente i vantaggi in termini di 
performance.

In particolare, nel nostro specifico caso, salta fuori che il metodo suggerito 
da Marco
sia *piu' veloce* di quello suggerito da te, che asserisci essere piu' veloce 
non mi
e' chiaro sulla base di cosa.

% /usr/bin/python2.6 oddrandom.py
baseline : 0.0180490016937
bit manip: 2.38537406921
randrange: 2.28163599968


Certo, non *molto* piu' veloce. Su un milione di esecuzioni circa un decimo di 
secondo.
Fossero stati i risultati invertiti, non mi sarei preoccupato ugualmente.

Quindi, di fatto e' il classico esempio di ottimizzazione prematura. Anzi, 
un'ottimizzazione
che *peggiora* le performance (e la leggibilita'). 

Tra l'altro, quando si fanno simulazioni numeriche, spesso si accetta di rifare 
piu' volte
gli esperimenti (quindi "di fatto" peggiorando il tempo di esecuzione di un 
fattore lineare)
pur di provarli con diversi generatori di numeri per mettersi al riparo da 
problemi di 
non troppo pseudo-casualita'. Quindi, figuriamoci. :)


> Per non giocare con i bit uno puo' fare randint(0,4) * 2 + 1 e ottiene
> i dispari tra 1 e 9, tanto equiprobabili quanto randint(0,4).
> Nel caso di randint(0,9) | 1 , ogni risultato ha esattamente due
> possibilita' di uscire: era il pari immediatamente superiore a cui si
> e' aggiunto 1, oppure era direttamente dispari, e non e' cambiato.

No, hai *perso* informazione. Eventualmente una quantita' completamente 
trascurabile,
possibilmente una quantita' rilevante. Con la semplice assunzione che ognuno dei
32 bit sia responsabile per 1/32 della qi, il primo modo fa una trasformazione 
lineare
(e quindi di fatto anche la qi rimane invariata). Con il tuo trucco invece 
perdi 1/32 della
qi. Non tanto, ma nemmeno poco. Dopotutto, visto che si puo' evitare il tutto.

Questo *a monte* del fatto che stai scegliendo su un range ristretto di numeri, 
eh.
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a