python 装饰器/Cprofile计算函数执行时间

用简单的堆排序来查看这些工具
今天先看一些内建工具

自己写一个装饰器

注释掉的部分是将尾递归省略掉的方法,理论上会提升效率,我用来做比较的

wujingcideMacBook-Pro:test wujingci$ cat dp.py
# encoding: utf-8
import random
from functools import wraps
import time

def timefn(function):
    @wraps(function)
    def count_time(*args, **kwargs):
        t1 = time.time()
        result = function(*args, **kwargs)
        t2 = time.time()
        print (function.func_name + ' took ' + str(t2-t1) + ' seconds')
        return result
    return count_time

heap_size = 0
LEFT = lambda i: 2*i+1
RIGHT = lambda i: 2*i+2
# 维护最大堆
def HEAPIFY(A, i):
    l, r = LEFT(i), RIGHT(i)
    largest = l if l < heap_size and A[l] > A[i] else i # 最小堆则改为 A[l] < A[i]
    largest = r if r < heap_size and A[r] > A[largest] else largest # 最小堆则改为A[r] < A[largest]
    if i != largest:
        A[i], A[largest] = A[largest], A[i]
        HEAPIFY(A,largest)
# 去除尾递归
#def HEAPIFY(A, i):
#    while True:
#        l, r = LEFT(i), RIGHT(i)
#        largest = l if l < heap_size and A[l] > A[i] else i
#        largest = r if r < heap_size and A[r] > A[largest] else largest
#        if i == largest: break
#        A[i], A[largest] = A[largest], A[i]
#        i = largest
# 构建最大堆
def BUILD_MAX_HEAP(A):
    global heap_size
    heap_size = len(A)
    for i in range(len(A)//2-1,-1,-1):
        HEAPIFY(A,i)
# 堆排序
def HEAPSORT(A):
    global heap_size
    BUILD_MAX_HEAP(A)
    for i in range(len(A)-1,-1,-1):
        A[i], A[0] = A[0], A[i]
        heap_size -= 1
        HEAPIFY(A,0)

@timefn
def main():
    a = []
    for i in range(10000):
        a.append(random.randint(0,100000))
    print 'before'
    print a
    print '\nafter'
    HEAPSORT(a)
    print a

if __name__ == "__main__":
    main()

跑一下,运行了main took 0.189006090164 seconds
这个是有差异化的,不过我们可以试着去掉尾递归main took 0.150513887405 seconds
貌似快一点,不过这说明不了什么,因为随机产生的数列要进行的元素交换次数不一样

用unix的time命令

将装饰器注释掉

time -p python dp.py
real         0.14
user         0.10
sys          0.01

用cprofile

         428031 function calls (313707 primitive calls) in 0.183 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    0.183    0.183 dp.py:2(<module>)
        1    0.017    0.017    0.175    0.175 dp.py:52(main)
        1    0.004    0.004    0.143    0.143 dp.py:43(HEAPSORT)
129324/15000    0.109    0.000    0.138    0.000 dp.py:20(HEAPIFY)
   129324    0.015    0.000    0.015    0.000 dp.py:17(<lambda>)
   129324    0.014    0.000    0.014    0.000 dp.py:18(<lambda>)
    10000    0.003    0.000    0.014    0.000 random.py:238(randint)
        1    0.001    0.001    0.012    0.012 dp.py:37(BUILD_MAX_HEAP)
    10000    0.010    0.000    0.010    0.000 random.py:175(randrange)
        1    0.003    0.003    0.007    0.007 random.py:40(<module>)
        1    0.003    0.003    0.003    0.003 hashlib.py:56(<module>)
    10000    0.001    0.000    0.001    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.001    0.001 random.py:91(__init__)
        1    0.000    0.000    0.001    0.001 random.py:100(seed)
    10000    0.001    0.000    0.001    0.000 {method 'random' of '_random.Random' objects}
        1    0.000    0.000    0.000    0.000 {function seed at 0x1061a8ed8}
        3    0.000    0.000    0.000    0.000 {range}
        1    0.000    0.000    0.000    0.000 {posix.urandom}
        6    0.000    0.000    0.000    0.000 hashlib.py:100(__get_openssl_constructor)
        1    0.000    0.000    0.000    0.000 random.py:72(Random)
        1    0.000    0.000    0.000    0.000 {binascii.hexlify}
        2    0.000    0.000    0.000    0.000 {math.log}
        1    0.000    0.000    0.000    0.000 {math.exp}
        1    0.000    0.000    0.000    0.000 __future__.py:48(<module>)
        6    0.000    0.000    0.000    0.000 {getattr}
        1    0.000    0.000    0.000    0.000 {method 'union' of 'set' objects}
        1    0.000    0.000    0.000    0.000 random.py:655(WichmannHill)
        1    0.000    0.000    0.000    0.000 random.py:805(SystemRandom)
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_md5}
        3    0.000    0.000    0.000    0.000 {len}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha224}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha256}
        7    0.000    0.000    0.000    0.000 __future__.py:75(__init__)
        1    0.000    0.000    0.000    0.000 {math.sqrt}
        1    0.000    0.000    0.000    0.000 __future__.py:74(_Feature)
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha1}
        6    0.000    0.000    0.000    0.000 {globals}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha512}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha384}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

去除尾递归的结果

         313689 function calls in 0.153 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.001    0.001    0.153    0.153 dp.py:2(<module>)
        1    0.016    0.016    0.144    0.144 dp.py:52(main)
        1    0.003    0.003    0.114    0.114 dp.py:43(HEAPSORT)
    15000    0.081    0.000    0.110    0.000 dp.py:27(HEAPIFY)
   129315    0.015    0.000    0.015    0.000 dp.py:17(<lambda>)
   129315    0.014    0.000    0.014    0.000 dp.py:18(<lambda>)
    10000    0.003    0.000    0.013    0.000 random.py:238(randint)
        1    0.001    0.001    0.010    0.010 dp.py:37(BUILD_MAX_HEAP)
    10000    0.009    0.000    0.010    0.000 random.py:175(randrange)
        1    0.004    0.004    0.008    0.008 random.py:40(<module>)
        1    0.003    0.003    0.003    0.003 hashlib.py:56(<module>)
        1    0.000    0.000    0.001    0.001 random.py:91(__init__)
        1    0.000    0.000    0.001    0.001 random.py:100(seed)
    10000    0.001    0.000    0.001    0.000 {method 'append' of 'list' objects}
    10000    0.001    0.000    0.001    0.000 {method 'random' of '_random.Random' objects}
        1    0.001    0.001    0.001    0.001 {function seed at 0x1085b5ed8}
        3    0.000    0.000    0.000    0.000 {range}
        1    0.000    0.000    0.000    0.000 {posix.urandom}
        1    0.000    0.000    0.000    0.000 {binascii.hexlify}
        6    0.000    0.000    0.000    0.000 hashlib.py:100(__get_openssl_constructor)
        1    0.000    0.000    0.000    0.000 __future__.py:48(<module>)
        2    0.000    0.000    0.000    0.000 {math.log}
        1    0.000    0.000    0.000    0.000 random.py:72(Random)
        1    0.000    0.000    0.000    0.000 {math.exp}
        6    0.000    0.000    0.000    0.000 {getattr}
        1    0.000    0.000    0.000    0.000 {method 'union' of 'set' objects}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_md5}
        7    0.000    0.000    0.000    0.000 __future__.py:75(__init__)
        1    0.000    0.000    0.000    0.000 random.py:655(WichmannHill)
        3    0.000    0.000    0.000    0.000 {len}
        1    0.000    0.000    0.000    0.000 random.py:805(SystemRandom)
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha512}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha256}
        1    0.000    0.000    0.000    0.000 {math.sqrt}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha384}
        1    0.000    0.000    0.000    0.000 __future__.py:74(_Feature)
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha1}
        1    0.000    0.000    0.000    0.000 {_hashlib.openssl_sha224}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        6    0.000    0.000    0.000    0.000 {globals}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

调用的函数次数要少一些

你可能感兴趣的:(python,实战)