sembra che la gamma è noto . Supponiamo che si va fino a 1 < < 20, solo per renderlo più interessante:
max_log2=20
Quindi, fare una lista che (in effetti) associa un numero intero per la sua base di 2 logaritmi. Di seguito farà il trucco:
log2s_table=[0]*((1<<max_log2)+1)
for i in range(max_log2+1):
log2s_table[1<<i]=i
(Questo non fa niente di utile per i numeri che non sono potenze di due, la dichiarazione del problema suggerisce che non hanno bisogno di essere trattati sarebbe abbastanza facile. risolvere questo però)
la funzione per ottenere il logaritmo è molto semplice, e potrebbe facilmente essere inline:.
def table(v):
return log2s_table[v]
non posso garantire che il codice di prova che ho scritto è esattamente la stessa di quella essere utilizzato per ottenere i tempi di esempio, ma questo è piuttosto più veloce dello.471.010.285,66321 milione codice:
stringcount: 0.43 s.
table: 0.16 s.
Poiché tutti i valori nella tabella sono meno di 256, mi chiese se utilizzare una stringa invece di un elenco sarebbe più veloce, o forse un array.array
di byte, ma nessun dadi:
string: 0.25 s.
arr: 0.21 s.
Utilizzando un dict
per fare la ricerca è un'altra possibilità, sfruttando il modo in cui solo potenze di due vengono controllati:
log2s_map=dict([(1<<x,x) for x in range(max_log2+1)])
def map(v):
return log2s_map[v]
I risultati di questo non erano buoni, però:
map: 0.20 s.
E solo per divertimento si potrebbe anche utilizzare il metodo hex
su oggetti galleggianti per ottenere una stringa che include (come la sua ultima parte) la base 2 esponente il numero.Questo è un po 'lento per estrarre in generale, ma se l'esponente è sempre e solo sarà una cifra che potrebbe essere fatto abbastanza semplicemente:
def floathex(v):
return ord(float(v).hex()[-1])-48
Questo è puramente per valore di intrattenimento anche se, come è stato uncompetetive - anche se , incredibilmente, ancora più veloce dell'approccio bit a bit.
Quindi sembra che usare una lista sia la strada da percorrere.
(Questo approccio non si ridimensionerà indefinitamente a causa della memoria limitata, ma per compensare che la velocità di esecuzione non dipenderà da max_log2
o dai valori di input, in alcun modo che si noterà quando si esegue python Per quanto riguarda il consumo di memoria, se ricordo correttamente i miei interni Python, la tabella occuperà circa (1<<max_log2)*4
byte, perché i contenuti sono tutti interi piccoli che l'interprete eseguirà internamente, quindi, quando max_log2
è 20, è circa 4 MB.)
Volevo solo aggiungere due riferimenti. Il primo, Fast Bytecodes for Funny Languages di Cliff Cock, http://www.infoq.com/presentations/click-fast-bytecodes-funny-languages del JVM Languages Summit 2008 che discute le ottimizzazioni utilizzate e perse dalle lingue "meno comuni" . Il secondo è Trucchi per l'ottimizzazione del compilatore C allo stato dell'arte http://lambda-the-ultimate.org/node/3674 di Felix von Leitner, presentato a Linux Kongress 2009, tratta dell'abilità del compilatore (ambiente) in questi giorni, e perché dovresti fare molta attenzione quando pensi di dover usare i trucchi di Michael Abrash. – mctylr
@mctylr - Grazie per i riferimenti (+1) – mac