W języku Python są wyrażenia takie jak 10**9
wykonane z literałów również literałów? O co pytam: Czy koszt używania wyrażeń jest mniej znaczący, ale także mniej obliczalne literały w kodzie, który jest nazywany bardzo często i powinien być lekki?Koszt korzystania z 10 ** 9 ponad 1000000000?
Odpowiedz
Chodzi bardziej o czytelność i styl kodowania. Pisząc coś takiego jak 10**9
zamiast 1000000000
itp., Sprawisz, że twój kod będzie krótszy i bardziej czytelny, a więc jego konserwacja i doskonalenie będzie łatwiejsze. Jeśli chcesz wielokrotnie używać kodu 10**9
w swoim kodzie, jako bardziej elegancki sposób lepiej użyj go jako zmiennej globalnej na najwyższym poziomie modułu, który jest bardziej elegancki. Jak:
MY_VARIABLE = 10**9
Uwaga, że nawet jeśli nie korzystają z globalną nazwę zmiennej i użyć jej wartość liczbową za pośrednictwem kodu Pythona będzie zakładać, że jest to wartość stała i nie będzie przeliczyć to za każdym razem.
Na przykład, jak widać na poniższym kodu bajtowego Python załaduje wartość stałą (co zdefiniowano w pierwszej części za a
) dla c
i nie tworzy nowy obiekt za to:
>>> 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
Uwaga że Python małych liczb całkowitych są singletons i python stworzy tylko jedną kopię nich (-5 do 256).
Nie ma żadnych kosztów wydajności. Rozważ to:
import dis
def foo():
x = 10**9
y = 10**9
def bar():
x = 1000000000
y = 1000000000
dis.dis(foo)
dis.dis(bar)
daje
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
Więc kiedy Python kompiluje kod, zmienia 10**9
do 1000000000
. Do czasu uruchomienia kodu bajtowego nie ma różnicy między używaniem 10**9
lub 1000000000
.
Myślę, że to "stałe składanie" jest jednak szczegółem implementacji cpython. – wim
Po autorefleksji, zrobiłem kilka pomiarów czasowych:
>>> import timeit
>>> def f():
... return 10**9
>>> timeit.timeit(f)
0.13885498046875
>>> def f():
... return 1000000000
>>> timeit.timeit(f)
0.13900208473205566
Nie jest koszt do używania wyrażeń, a mianowicie koszt wydajność ze względu na Python precomputing constant expressions, ale koszt ten nie jest prawdopodobne, aby być zauważalne w większości przypadków, jak w przypadku 10**9
, w przypadku takich przypadków jak 10**(10**10)
.
Dobry odnośnik! Więc to, co mówisz, to to, że dodawana jest obliczalność, ale jednorazowa kompilacja? – ArekBulski
Nie jest bardziej czytelny, ponieważ jest krótszy. Jest bardziej czytelny, ponieważ nie trzeba liczyć zer. –
@Rhymoid Rzeczywiście, i to miałem na myśli. – Kasramvd
nit: twój b to 10 ** 8 – wim