关于python:在主函数中包装代码使其运行更快

Wrapping code in main function makes it run much faster

本问题已经有最佳答案,请猛点这里访问。

试图理解Python中的这种现象。当我将代码包装成一个函数时,它的速度会提高30%以上!!!!到目前为止,我没有在谷歌上找到任何合理的解释。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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秒,但是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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秒。

为什么会这样????


不同之处在于,Python使用不同的字节码操作来访问函数的局部变量和模块的全局变量。用于访问局部变量的加载快速操作码采用数字索引并执行快速数组查找以检索值。用于访问全局变量的加载名称和加载全局操作码取一个名称并执行哈希表查找(可能在多个哈希表中)以检索值。

通过将代码包装在函数中,可以有效地将所有变量从全局转换为局部变量,从而可以更快地访问这些变量。