试图在Python中理解这种现象。当我将代码包装到函数中时,它的速度提高了30%以上!到目前为止,我没有说出任何合理的解释。
例如:
import sys
sys.stdin = open("dd.txt")
import cProfile
import time
t0 = time.time()
def main():
from collections import defaultdict
n, T = map(int, raw_input().split())
tree = defaultdict(lambda: set())
root = None
for _ in xrange(n - 1):
a, b = map(int, raw_input().split())
tree[a].add(b)
tree[b].add(a)
if not root:
root = a
count = 0
stack = [root]
links = dict()
links[root] = 0
mem = dict()
while stack:
node = stack.pop()
path = list()
path.append(node)
lnk = links[node]
while lnk:
if lnk not in mem:
if abs(lnk - node) <= T:
count += 1
path.append(lnk)
lnk = links[lnk]
else:
path.extend(mem[lnk])
for el in mem[lnk]:
if abs(el - node) <= T:
count += 1
break
#print node, path
plen = len(path)
mem[node] = path
for next_node in tree[node]:
if plen <= 1 or next_node != path[1]:
links[next_node] = node
stack.append(next_node)
print count
main()
print time.time() - t0
这会将运行时间打印为2.5秒,但是:
import sys
sys.stdin = open("dd.txt")
import cProfile
import time
t0 = time.time()
#def main():
from collections import defaultdict
n, T = map(int, raw_input().split())
tree = defaultdict(lambda: set())
root = None
for _ in xrange(n - 1):
a, b = map(int, raw_input().split())
tree[a].add(b)
tree[b].add(a)
if not root:
root = a
count = 0
stack = [root]
links = dict()
links[root] = 0
mem = dict()
while stack:
node = stack.pop()
path = list()
path.append(node)
lnk = links[node]
while lnk:
if lnk not in mem:
if abs(lnk - node) <= T:
count += 1
path.append(lnk)
lnk = links[lnk]
else:
path.extend(mem[lnk])
for el in mem[lnk]:
if abs(el - node) <= T:
count += 1
break
#print node, path
plen = len(path)
mem[node] = path
for next_node in tree[node]:
if plen <= 1 or next_node != path[1]:
links[next_node] = node
stack.append(next_node)
print count
#main()
print time.time() - t0
简单地将代码移出main()函数会使其运行3.5秒而不是2.5秒。
这可能是什么原因???
答案 0 :(得分:6)
不同之处在于Python使用不同的字节码操作来访问函数的局部变量和模块的全局变量。用于访问局部变量的LOAD_FAST操作码采用数字索引并执行快速数组查找以检索值。用于访问全局变量的LOAD_NAME和LOAD_GLOBAL操作码采用名称并执行哈希表查找(可能在多个哈希表中)以检索值。
通过将代码包装在函数中,您可以有效地将所有变量从全局变换为本地变量,这样可以更快地访问它们。