Python 函數調用性能記錄

以前用 JS 寫項目的時候,項目組用的組件模式,一直感受很不錯。最近用 Python 作新項目,項目結構也延續了組件模式。一直沒有對函數調用的性能做了解,今天突發奇想測試了一下,寫了一些測試代碼python

 

首先定義了幾個 class :緩存

class A(object):
    def test(self):
        pass

class B(object):
    def __init__(self):
        self.a = A()

    def test(self):
        pass

class C(object):
    def __init__(self):
        self.b = B()

    def test(self):
        pass

class D(object):
    def __init__(self):
        self.c = C()
    def test(self):
        pass

 

對比1:函數

直接調用實例對象身上的方法 和 使用變量緩存該方法而後調用性能

n = 10000000
import timeit

a = A()
t_direct = timeit.Timer('a.test()', 'from __main__ import a').timeit(n)
print 'direct call func : ', t_direct

cache = a.test
t_cache = timeit.Timer('cache()', 'from __main__ import cache').timeit(n)
print 'cache func call  : ', t_cache

print ' performance : ', (t_cache / t_direct)

 

嘗試屢次後得出該狀況下的時間結論:測試

direct call func :  1.14136314392
cache func call  :  0.745277881622
 performance :  0.652971743123

緩存方法以後再調用,性能大約能提高 35%spa

調用函數時,python 會臨時建立一個對象,好比直接調用函數 a.test() 時,python 會執行以下步驟:code

1: temp = a.testorm

2: temp()對象

3: del tempblog

因此頻繁調用時,性能上是一個問題。內存上應該也是一個問題,感受會更加頻繁的觸發 gc

 

對比2:

經過成員變量多層調用一個函數,和直接調用對象身上的函數的性能差

t0 = timeit.Timer('d.test()', 'from __main__ import d').timeit(n)
print '0 level:  ', t0

t1 = timeit.Timer('d.c.test()', 'from __main__ import d').timeit(n)
print '1 level:  ', t1, '    : ', (t1 / t0) * 100

t2 = timeit.Timer('d.c.b.test()', 'from __main__ import d').timeit(n)
print '2 level:  ', t2, '    : ', (t2 / t1) * 100, '    ', (t2 / t0 * 100)

t3 = timeit.Timer('d.c.b.a.test()', 'from __main__ import d').timeit(n)
print '3 level:  ', t3, '    : ', (t3 / t2) * 100, '    ', (t3 / t0 * 100)

 

嘗試屢次後得出該狀況下的時間結論:

0 level:   1.26769399643

1 level:   1.50338602066     :  118.592185882

2 level:   1.74297595024     :  115.936687337      137.491851752

3 level:   1.87865877151     :  107.784549251      148.194972667

基本上,函數調用層次多一層,性能消耗會多 5% 到 15% 左右

這個暫時沒法詳細的解答。手上也沒有 JS 的測試數據,不肯定當時 js 些寫項目的時候,是否也存在這個性能問題。

 

以前碰到一些項目的結構是,寫的時候分紅了多個文件來寫,可是最後運行的時候,會把這多個文件中定義的 屬性、函數都聚合到一個 class 身上,成爲一個巨無霸級的 class。一直不理解這麼作的意義是什麼,感受很臃腫,如今看來 估計爲了減小函數調用的層次,提升性能。

相關文章
相關標籤/搜索