Zaskoczyło mnie, że nie opublikowałem już faktycznych liczb kosztów powtórnych kontroli obciążenia, chociaż istnieje wiele dobrych wyjaśnień, czego można się spodziewać.
Jeśli importujesz u góry, to niezależnie od tego, jaki ładunek trafisz. To dość małe, ale zwykle w milisekundach, a nie nanosekundach.
Jeśli importujesz w ramach funkcji, wtedy trafiasz tylko do załadowania, jeśli i kiedy jedna z tych funkcji jest wywoływana po raz pierwszy. Jak wielu zauważyło, jeśli tak się nie stanie, oszczędzasz czas ładowania. Ale jeśli funkcja (y) nazywa się dużo, można podjąć powtarzające się mimo znacznie mniejszej trafienia (dla sprawdzenia, że został załadowany; nie za faktycznie przeładunkowych). Z drugiej strony, jak zauważył @aaronasterling, oszczędzasz również trochę, ponieważ importowanie w funkcji pozwala funkcji na nieco szybsze wyszukiwanie zmiennych lokalnych w celu późniejszego zidentyfikowania nazwy ( http://stackoverflow.com/questions/477096/python- import-koding-style / 4789963 # 4789963 ).
Oto wyniki prostego testu, który importuje kilka rzeczy z wnętrza funkcji. Podane czasy (w Pythonie 2.7.14 na procesorze Intel Core i7 2,3 GHz) pokazano poniżej (drugie połączenie odbierające więcej niż później wydaje się spójne, choć nie wiem dlaczego).
0 foo: 14429.0924 µs
1 foo: 63.8962 µs
2 foo: 10.0136 µs
3 foo: 7.1526 µs
4 foo: 7.8678 µs
0 bar: 9.0599 µs
1 bar: 6.9141 µs
2 bar: 7.1526 µs
3 bar: 7.8678 µs
4 bar: 7.1526 µs
Kod:
from __future__ import print_function
from time import time
def foo():
import collections
import re
import string
import math
import subprocess
return
def bar():
import collections
import re
import string
import math
import subprocess
return
t0 = time()
for i in xrange(5):
foo()
t1 = time()
print(" %2d foo: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
t0 = t1
for i in xrange(5):
bar()
t1 = time()
print(" %2d bar: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
t0 = t1