亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python 性能提升的幾種方法

系統 1921 0

關于python 性能提升的一些方案。

一、函數調用優化(空間跨度,避免訪問內存)

?程序的優化核心點在于盡量減少操作跨度,包括代碼執行時間上的跨度以及內存中空間跨度。

1.大數據求和,使用sum

            
a = range(100000)
%timeit -n 10 sum(a)
10 loops, best of 3: 3.15 ms per loop
%%timeit
  ...: s = 0
  ...: for i in a:
  ...:  s += i
  ...:
100 loops, best of 3: 6.93 ms per loop
          

2.小數據求和,避免使用sum

            
%timeit -n 1000 s = a + b + c + d + e + f + g + h + i + j + k # 數據量較小時直接累加更快
1000 loops, best of 3: 571 ns per loop
%timeit -n 1000 s = sum([a,b,c,d,e,f,g,h,i,j,k]) # 小數據量調用 sum 函數,空間效率降低
1000 loops, best of 3: 669 ns per loop
          

結論:大數據求和sum效率高,小數據求和直接累加效率高。

二、for循環優化之取元素(使用棧或寄存器,避免訪問內存)

            
for lst in [(1, 2, 3), (4, 5, 6)]: # lst 索引需要額外開銷
  pass
          

 應盡量避免使用索引。

            
for a, b, c in [(1, 2, 3), (4, 5, 6)]: # better
  pass
          

相當于給每一個元素直接賦值。

            
def force():
 lst = range(4)
 for a1 in [1, 2]:
   for a2 in lst:
     for a3 in lst:
       for b1 in lst:
         for b2 in lst:
           for b3 in lst:
             for c1 in lst:
               for c2 in lst:
                 for c3 in lst:
                   for d1 in lst:
                     yield (a1, a2, a3, b1, b2, b3, c1, c2, c3, d1)
                      
%%timeit -n 10
for t in force():
  sum([t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9]])
10 loops, best of 3: 465 ms per loop
%%timeit -n 10
for a1, a2, a3, b1, b2, b3, c1, c2, c3, d1 in force():
  sum([a1, a2, a3, b1, b2, b3, c1, c2, c3, d1])
10 loops, best of 3: 360 ms per loop
          

三、生成器優化(查表代替運算)

            
def force(start, end): # 用于密碼暴力破解程序
  for i in range(start, end):
    now = i
    sublst = []
    for j in range(10):
      sublst.append(i % 10) # 除法運算開銷較大,比乘法大
      i //= 10
    sublst.reverse()
    yield(tuple(sublst), now)
          
            
def force(): # better
 lst = range(5)
 for a1 in [1]:
   for a2 in lst:
     for a3 in lst:
       for b1 in lst:
         for b2 in lst:
           for b3 in lst:
             for c1 in lst:
               for c2 in lst:
                 for c3 in lst:
                   for d1 in lst:
                     yield (a1, a2, a3, b1, b2, b3, c1, c2, c3, d1)
  
          
            
r0 = [1, 2] # 可讀性與靈活性
r1 = range(10)
r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r1
force = ((a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
      for a0 in r0 for a1 in r1 for a2 in r2 for a3 in r3 for a4 in r4
      for a5 in r5 for a6 in r6 for a7 in r7 for a8 in r8 for a9 in r9)
          

?四、冪運算優化(pow(x,y,z)) 

            
def isprime(n):
  if n & 1 == 0:
    return False
  k, q = find_kq(n)
  a = randint(1, n - 1)
  if pow(a, q, n) == 1: # 比使用 a ** q % n 運算優化數倍
    return True
  for j in range(k):
    if pow(a, pow(2, j) * q, n) == n - 1: # a **((2 ** j) * q) % n
      return True
  return False
          

?結論:pow(x,y,z)優于x**y%z.

?五、除法運算優化

            
In [1]: from random import getrandbits
 
In [2]: x = getrandbits(4096)
 
In [3]: y = getrandbits(2048)
 
In [4]: %timeit -n 10000 q, r = divmod(x, y)
10000 loops, best of 3: 10.7 us per loop
 
In [5]: %timeit -n 10000 q, r = x//y, x % y
10000 loops, best of 3: 21.2 us per loop
          

?結論:divmod優于//和%。

? 六、優化算法時間復雜度 

算法的時間復雜度對程序的執行效率影響最大,在python中可以選擇合適的數據結構來優化時間復雜度,如list和set查找某一個元素的時間復雜度分別是O(n)和O(1)。不同場景有不同的優化方式,總的來說,一般有分治,分支定界、貪心動態規劃等思想。

七、合理使用copy和deepcopy  

對于dict和list等數據結構的對象,直接賦值使用的是引用的方式。而有些情況下需要復制整個對象,這時可以使用copy包里的copy和deepcopy,這兩個函數的不同之處在于deepcopy是遞歸復制的。效率不同:

            
In [23]: import copy
In [24]: %timeit -n 10 copy.copy(a)
10 loops, best of 3: 606 ns per loop
In [25]: %timeit -n 10 copy.deepcopy(a)
10 loops, best of 3: 1.17 us per loop
          

?timeit后面的-n表示運行的次數,后兩行對應的是兩個timeit的輸出,下同。由此可見后者慢一個數量級。

?關于copy的一個例子:

            
>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]
          

?發生的事情是這樣的,[[]]是包含一個空列表的只有一個元素的列表,所以[[]] * 3的所有三個元素都是(指向)這個空列表。修改lists的任何元素都修改這個列表。修改效率高。

?八、使用dict或set查找元素

python 字典和集合都是使用hash表來實現(類似c++標準庫unordered_map),查找元素的時間復雜度是O(1)。

            
In [1]: r = range(10**7)
In [2]: s = set(r) # 占用 588MB 內存
In [3]: d = dict((i, 1) for i in r) # 占用 716MB 內存
In [4]: %timeit -n 10000 (10**7) - 1 in r
10000 loops, best of 3: 291 ns per loop
In [5]: %timeit -n 10000 (10**7) - 1 in s
10000 loops, best of 3: 121 ns per loop
In [6]: %timeit -n 10000 (10**7) - 1 in d
10000 loops, best of 3: 111 ns per loop
          

結論:set 的內存占用量最小,dict運行時間最短。

九、合理使用(generator)和yield(節省內存)

            
In [1]: %timeit -n 10 a = (i for i in range(10**7)) # 生成器通常遍歷更高效
10 loops, best of 3: 933 ns per loop
In [2]: %timeit -n 10 a = [i for i in range(10**7)]
10 loops, best of 3: 916 ms per loop
In [1]: %timeit -n 10 for x in (i for i in range(10**7)): pass
10 loops, best of 3: 749 ms per loop
In [2]: %timeit -n 10 for x in [i for i in range(10**7)]: pass
10 loops, best of 3: 1.05 s per loop
          

結論:盡量使用生成器去遍歷。

以上就是對python 性能提升的一些方案,后續繼續補充,需要的可以看下。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一级淫片免费视频 | 伊人网在线视频 | 国产欧美综合在线一区二区三区 | 欧美激情区 | 特级毛片a级毛免费播放 | 激情小视频在线播放免费 | 在线播放 亚洲 | 老子影院午夜伦手机不卡6080 | 久久精品国产夜色 | 天天操视频 夜夜 | 九九热视频在线播放 | 99热在线精品播放 | 亚洲精品久久久久福利网站 | 国产69精品久久久久99尤物 | 色婷婷综合久久久久中文 | 亚洲视频高清 | 欧美日韩综合在线视频免费看 | www.亚洲一区二区三区 | jizzjizz欧美69巨大 | 久久大综合| 天天干人人 | 久久99国产精品久久欧美 | 日本中文在线观看 | 中文字幕中文字幕在线 | 精品久久久久久久免费加勒比 | 久久天天躁狠狠躁夜夜不卡 | 亚洲精品国产成人99久久 | 国产精品一区在线观看 | 香蕉爱视频 | 国产精品6 | 性做久久久久久坡多野结衣 | 亚洲欧美国产精品专区久久 | 呦呦国产| 国语精品91自产拍在线观看二区 | 狠狠色狠狠色综合网 | 一级毛片不收费 | 亚洲免费大片 | 2018久久久国产精品 | 亚洲国产爱久久全部精品 | 国内精品久久久久久久 | 国产亚洲精品久久综合影院 |