In Python, le espressioni come 10**9
fatte di letterali sono anche letterali? Quello che sto chiedendo: c'è un costo per usare le espressioni su letterali meno significativi ma anche meno calcolabili nel codice che viene chiamato molto spesso e dovrebbe essere leggero?Il costo dell'utilizzo di 10 ** 9 su 1000000000?
risposta
Si tratta di leggibilità e stile di codifica. Scrivendo qualcosa come 10**9
invece di 1000000000
o ecc., Il codice verrà ridotto e più leggibile, pertanto la manutenzione e il miglioramento saranno più semplici. Se si desidera utilizzare 10**9
più volte nel codice, in un modo più elegante è preferibile utilizzarlo come variabile globale al livello più alto del modulo che è più elegante. Come:
MY_VARIABLE = 10**9
Nota che anche se non si utilizza un nome di variabile globale e utilizzare il suo valore numerico tramite il codice Python assumerà si tratta di un valore costante e non sarà ricalcolare ogni volta.
Ad esempio, come si può vedere nella seguente bytecode, pitone caricherà il valore costante (che definita in prima parte di a
) per c
e non crea un nuovo oggetto per questo:
>>> def test():
... a = 10**9
... b = 1000000000
... c = 10**9
...
>>> dis.dis(test)
2 0 LOAD_CONST 4 (1000000000)
3 STORE_FAST 0 (a)
3 6 LOAD_CONST 3 (1000000000)
9 STORE_FAST 1 (b)
4 12 LOAD_CONST 5 (1000000000)
15 STORE_FAST 2 (c)
18 LOAD_CONST 0 (None)
21 RETURN_VALUE
Nota che Python piccoli interi sono single e pitone creerà una sola copia di loro (da -5 a 256).
Non ci sono costi di prestazioni. Considerate questo:
import dis
def foo():
x = 10**9
y = 10**9
def bar():
x = 1000000000
y = 1000000000
dis.dis(foo)
dis.dis(bar)
cede
In [6]: dis.dis(foo)
5 0 LOAD_CONST 3 (1000000000)
3 STORE_FAST 0 (x)
6 6 LOAD_CONST 4 (1000000000)
9 STORE_FAST 1 (y)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
In [8]: dis.dis(bar)
9 0 LOAD_CONST 1 (1000000000)
3 STORE_FAST 0 (x)
10 6 LOAD_CONST 1 (1000000000)
9 STORE_FAST 1 (y)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Così, quando Python compila il codice, cambia il 10**9
-1000000000
. Nel momento in cui viene eseguito il codice byte, non vi è alcuna differenza tra l'utilizzo di 10**9
o 1000000000
.
Penso che questo "piegamento costante" sia comunque un dettaglio di implementazione cpython. – wim
Dopo sé riflessione, ho fatto alcune misure di tempo:
>>> import timeit
>>> def f():
... return 10**9
>>> timeit.timeit(f)
0.13885498046875
>>> def f():
... return 1000000000
>>> timeit.timeit(f)
0.13900208473205566
Ci è un costo per usare le espressioni, vale a dire un costo delle prestazioni a causa di Python precomputing constant expressions, ma questo costo non è probabile che sia evidente nella maggior parte dei casi, come nel caso di 10**9
, più ancora con casi come 10**(10**10)
.
Buona referenza! Quindi quello che stai dicendo è che il calcolo è stato aggiunto, ma una volta in fase di compilazione? – ArekBulski
Non è più leggibile perché è più breve. È più leggibile perché non devi contare zero. –
@Rhymoid In effetti, ed era quello che intendevo. – Kasramvd
nit: il tuo b è 10 ** 8 – wim