一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - python 性能提升的幾種方法

python 性能提升的幾種方法

2020-09-02 09:15Python教程網(wǎng) Python

本篇文章主要介紹python 性能提升的幾種方法,并附有代碼參考示例,有需要的小伙伴可以參考下

關(guān)于python 性能提升的一些方案。

一、函數(shù)調(diào)用優(yōu)化(空間跨度,避免訪問內(nèi)存)

 程序的優(yōu)化核心點在于盡量減少操作跨度,包括代碼執(zhí)行時間上的跨度以及內(nèi)存中空間跨度。

1.大數(shù)據(jù)求和,使用sum

?
1
2
3
4
5
6
7
8
9
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.小數(shù)據(jù)求和,避免使用sum

?
1
2
3
4
%timeit -n 1000 s = a + b + c + d + e + f + g + h + i + j + k # 數(shù)據(jù)量較小時直接累加更快
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]) # 小數(shù)據(jù)量調(diào)用 sum 函數(shù),空間效率降低
1000 loops, best of 3: 669 ns per loop

結(jié)論:大數(shù)據(jù)求和sum效率高,小數(shù)據(jù)求和直接累加效率高。

二、for循環(huán)優(yōu)化之取元素(使用棧或寄存器,避免訪問內(nèi)存)

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

 應(yīng)盡量避免使用索引。

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

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

?
1
2
3
4
5
6
7
8
9
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)
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)
  
?
1
2
3
4
5
6
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)

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

?
1
2
3
4
5
6
7
8
9
10
11
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 運算優(yōu)化數(shù)倍
    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

 結(jié)論:pow(x,y,z)優(yōu)于x**y%z.

 五、除法運算優(yōu)化

?
1
2
3
4
5
6
7
8
9
10
11
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

 結(jié)論:divmod優(yōu)于//和%。

 六、優(yōu)化算法時間復(fù)雜度  

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

七、合理使用copy和deepcopy  

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

?
1
2
3
4
5
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表示運行的次數(shù),后兩行對應(yīng)的是兩個timeit的輸出,下同。由此可見后者慢一個數(shù)量級。

 關(guān)于copy的一個例子:

?
1
2
3
4
5
6
>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]

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

 八、使用dict或set查找元素

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

?
1
2
3
4
5
6
7
8
9
In [1]: r = range(10**7)
In [2]: s = set(r) # 占用 588MB 內(nèi)存
In [3]: d = dict((i, 1) for i in r) # 占用 716MB 內(nèi)存
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

結(jié)論:set 的內(nèi)存占用量最小,dict運行時間最短。

九、合理使用(generator)和yield(節(jié)省內(nèi)存)

?
1
2
3
4
5
6
7
8
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

結(jié)論:盡量使用生成器去遍歷。

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本海鸣馆| 高h舔穴 | t66y地址一地址二地址三 | 精东影业传媒全部作品 | 欧美性高清另类videosex死尸 | 四虎影院大全 | 国产趴着打光屁股sp抽打 | 91天堂素人 | juliaann厨房大战 | 国产婷婷成人久久av免费高清 | 美女毛片老太婆bbb80岁 | 日韩在线 在线播放 | 午夜综合网| 久久久久久久99精品免费观看 | 国产一级精品高清一级毛片 | 国内精品久久久久影院网站 | 四虎永久免费地址在线观看 | 久热在线这里只有精品7 | 99视频在线观看视频 | 欧美一级在线 | 免费在线观看日本 | 国产日本免费 | 美女撒尿无遮挡免费中国 | 欧美免赞性视频 | 无码专区aaaaaa免费视频 | 亚洲AVAV天堂AV在线网爱情 | 亚洲春色综合另类网蜜桃 | 俄罗斯13一14处出血视频在线 | 国产精品nv在线观看 | 奇米影视在线视频 | 欧美影院一区二区三区 | 亚洲国产精品日韩高清秒播 | 亚洲日本视频在线观看 | 日韩成人在线视频 | 欧美日韩一区二区综合在线视频 | 日本视频免费在线播放 | 波多野结衣不卡 | 成人夜视频寂寞在线观看 | 精品久久久久久久久免费影院 | 超级乱淫伦短篇小说做车 | 久久九九精品国产自在现线拍 |