在main函数中包装代码使其运行速度更快

时间:2015-02-02 08:00:35

标签: python

试图在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秒。

这可能是什么原因???

1 个答案:

答案 0 :(得分:6)

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

通过将代码包装在函数中,您可以有效地将所有变量从全局变换为本地变量,这样可以更快地访问它们。