怎么讓Python程序快一點(diǎn)運(yùn)行

本篇內(nèi)容介紹了“怎么讓Python程序快一點(diǎn)運(yùn)行”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站于2013年開始,先為麗水等服務(wù)建站,麗水等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為麗水企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

Python性能調(diào)試

要進(jìn)行Python性能,前提條件是要找出程序中的性能瓶頸。找出程序中影響程序性能的代碼。有經(jīng)驗(yàn)的開發(fā)者一般都能很容易能找出程序的瓶頸,但對(duì)于普通碼農(nóng)找出系統(tǒng)的問題代碼則很難,為了能快捷有效的發(fā)現(xiàn)程序的性能瓶頸就需要進(jìn)行性能調(diào)試,此處我們以一個(gè)實(shí)際例子進(jìn)行介紹,以下程序是計(jì)算e的x(1..n)次的冪,其代碼如下:

# performance.py  from decimal import *  def exp(x):  getcontext().prec += 2  i, lasts, s, fact, num = 0, 0, 1, 1, 1  while s != lasts:  lasts = s  i += 1  fact *= i  num *= x  s += num / fact  getcontext().prec -= 2  return +s  print(exp(Decimal(150)))  print(exp(Decimal(400)))  print(exp(Decimal(3000)))

最簡(jiǎn)單的調(diào)試

最簡(jiǎn)單且實(shí)用的調(diào)試性能調(diào)試的方法是使用Linux的time命令,time可以計(jì)算程序執(zhí)行的時(shí)間:

怎么讓Python程序快一點(diǎn)運(yùn)行
time python3 performance.py  1.393709580666379697318341937E+65  5.221469689764143950588763007E+173  7.646200989054704889310727660E+1302  real 0m15.185s  user 0m15.100s  sys 0m0.004s

計(jì)算前兩個(gè)數(shù)的(150,400)很快,而第三個(gè)大一點(diǎn)時(shí)會(huì)很慢,總共要15秒多才算完,是有點(diǎn)卡頓(慢)。

time雖然很便捷有用,但是不能給我們?cè)敿?xì)的代碼性能細(xì)節(jié)。

詳細(xì)性能分析cProfile

性能分析另一個(gè)常用的方法是使用cProfile,它可以提供很多性能信息

python3 -m cProfile -s time performance.py
怎么讓Python程序快一點(diǎn)運(yùn)行

例子中,我們使用了cProfile模塊和time參數(shù)運(yùn)行測(cè)試腳本,以便按內(nèi)部時(shí)間(cumtime)對(duì)行進(jìn)行排序。如上圖所示,使用cProfile可以給很多內(nèi)部的具體信息,通過我們可以知道主要耗時(shí)是由exp函數(shù)導(dǎo)致。知道了程序的性能瓶頸所在,我們就再說明Python性能分析和優(yōu)化。

優(yōu)化特定功能

知道了將性能的瓶頸所在(實(shí)例中是exp函數(shù)),我們?yōu)榱诉M(jìn)一步具體問題具體分析,我們使用一個(gè)簡(jiǎn)單裝飾器,以便跳過其他代碼,專門分析性能瓶頸所設(shè)計(jì)的函數(shù)。然后使用裝飾器進(jìn)行測(cè)試,具體代碼如下:

def timeit_wrapper(func):  @wraps(func)  def wrapper(*args, **kwargs):  start = time.perf_counter() # Alternatively, you can use time.process_time()  func_return_val = func(*args, **kwargs)  end = time.perf_counter()  print('{0:<10}.{1:<8} : {2:<8}'.format(func.__module__, func.__name__, end - start))  return func_return_val  return wrapper

我們用這個(gè)裝飾器來測(cè)試exp:

@timeit_wrapper  def exp(x):  ...  print('{0:<10} {1:<8} {2:^8}'.format('module', 'function', 'time'))  exp(Decimal(150))  exp(Decimal(400))  exp(Decimal(3000))
怎么讓Python程序快一點(diǎn)運(yùn)行

結(jié)果:

module function time  __main__ .exp : 0.00920036411844194  __main__ .exp : 0.09822067408822477  __main__ .exp : 15.228459489066154

代碼中,我們用到了time包提供time.perf_counter函數(shù),它還提供了另外一個(gè)函數(shù)time.process_time。兩者的區(qū)別在于perf_counter返回的絕對(duì)時(shí)間,包括Python程序進(jìn)程未運(yùn)行時(shí)的時(shí)間,它可能會(huì)受到計(jì)算機(jī)負(fù)載的影響。而process_time僅返回用戶時(shí)間(不包括系統(tǒng)時(shí)間),這僅是程序過程時(shí)間。

性能優(yōu)化

最后是Python程序的性能優(yōu)化,為了讓Python程序運(yùn)行得更快,我們提供一些可供參考的性能優(yōu)化構(gòu)想和策略的,通過這些策略我們一半可以提高應(yīng)用的運(yùn)行速度,最高情況下可以讓你的應(yīng)用快30%。

使用內(nèi)建數(shù)據(jù)類型

很明顯,內(nèi)建數(shù)據(jù)類型非常快,尤其是與自定義類型相比,比如樹或者鏈表。因?yàn)閮?nèi)建程序是用C實(shí)現(xiàn)的,所以其性能優(yōu)勢(shì)是Python代碼所無法比擬的。

使用lru_cache緩存/記憶

很多時(shí)候緩存非常有效,可以極大的提高性能,尤其在數(shù)值計(jì)算和涉及大量重復(fù)調(diào)用(遞歸)時(shí)??紤]一個(gè)例子:

怎么讓Python程序快一點(diǎn)運(yùn)行

上面的函數(shù)使用time.sleep(2)模擬一個(gè)耗時(shí)的代碼。第一次使用參數(shù)1調(diào)用時(shí),它將等待2秒,然后返回結(jié)果。再次調(diào)用時(shí),由于結(jié)果已被緩存,將跳過函數(shù)的執(zhí)行,直返回。用3調(diào)用時(shí)候由于參數(shù)不一樣會(huì)耗時(shí)2秒,總體耗時(shí)應(yīng)該為4s,我們用time  驗(yàn)證:

real 0m4.061s  user 0m0.040s  sys 0m0.015s

這和我們?cè)O(shè)想的一致。

使用局部變量

基于變量作用域中查找速度相關(guān),在函數(shù)的局部變量具有很高的速度。其次是類級(jí)屬性(如self.name)和最慢的是全局變量,如time.time(最慢)。所以我們可以通過避免使用不必要的全局變量來提高性能。

使用函數(shù)

這似乎有點(diǎn)出乎意料,因?yàn)樯婕昂瘮?shù)的內(nèi)存占用都在堆棧上,而函數(shù)返回也會(huì)有開銷。但是使用函數(shù),可以避免使用全局變量,可以提高性能。因此,可以通過將整個(gè)代碼包裝在main函數(shù)中只調(diào)用一次來加速代碼。

避免使用屬性

另一個(gè)可以是影響程序性能的操作是點(diǎn)運(yùn)算符訪問對(duì)象屬性。點(diǎn)運(yùn)算符使用__getattribute__觸發(fā)會(huì)字典查找,會(huì)在代碼中產(chǎn)生額外的開銷。我們可以通過一些使用函數(shù)而不是類方法的方式避免點(diǎn)操作,比如下面例子

#慢代碼:

import re  def slow_func():  for i in range(10000):  re.findall(regex, line)

#快代碼

from re import findall  def fast_func():  for i in range(10000):  findall(regex, line)

使用f-string

在循環(huán)中使用格式符(%s)或.format()時(shí),字符串操作可能會(huì)變得非常緩慢。為了進(jìn)行性能優(yōu)化,我們應(yīng)該使用f-string。它是Python  3.6引入的很具可讀性,簡(jiǎn)潔性和最快的方法。比如:

s + ' ' + t  ' '.join((s, t))  '%s %s' % (s, t)  '{} {}'.format(s, t)  Template('$s $t').substitute(s=s, t=t) # 慢代碼   f'{s} {t}' # 快代碼

“怎么讓Python程序快一點(diǎn)運(yùn)行”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

分享文章:怎么讓Python程序快一點(diǎn)運(yùn)行
標(biāo)題路徑:http://muchs.cn/article20/gpjdjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、全網(wǎng)營(yíng)銷推廣、標(biāo)簽優(yōu)化、網(wǎng)站內(nèi)鏈、定制網(wǎng)站、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)