99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀Python異常對代碼運(yùn)行性能的影響實(shí)例解析
Python異常對代碼運(yùn)行性能的影響實(shí)例解析
2018-04-29
收藏

Python異常對代碼運(yùn)行性能的影響實(shí)例解析

Python的異常處理能力非常強(qiáng)大,但是用不好也會帶來負(fù)面的影響。我平時(shí)寫程序的過程中也喜歡使用異常,雖然采取防御性的方式編碼會更好,但是交給異常處理會起到偷懶作用。偶爾會想想異常處理會對性能造成多大的影響,于是今天就試著測試了一下。
Python異常(谷歌開源風(fēng)格指南)
tip:
允許使用異常, 但必須小心。
定義:
異常是一種跳出代碼塊的正??刂屏鱽硖幚礤e(cuò)誤或者其它異常條件的方式。
優(yōu)點(diǎn):
正常操作代碼的控制流不會和錯(cuò)誤處理代碼混在一起. 當(dāng)某種條件發(fā)生時(shí), 它也允許控制流跳過多個(gè)框架. 例如, 一步跳出N個(gè)嵌套的函數(shù), 而不必繼續(xù)執(zhí)行錯(cuò)誤的代碼。
缺點(diǎn):
可能會導(dǎo)致讓人困惑的控制流. 調(diào)用庫時(shí)容易錯(cuò)過錯(cuò)誤情況。
結(jié)論:
異常必須遵守特定條件:
像這樣觸發(fā)異常: raise MyException("Error message") 或者 raise MyException . 不要使用兩個(gè)參數(shù)的形式( raise MyException, "Error message" )或者過時(shí)的字符串異常( raise "Error message" )。
模塊或包應(yīng)該定義自己的特定域的異?;? 這個(gè)基類應(yīng)該從內(nèi)建的Exception類繼承. 模塊的異?;悜?yīng)該叫做”Error”。    
class Error(Exception):
  pass
永遠(yuǎn)不要使用 except: 語句來捕獲所有異常, 也不要捕獲 Exception 或者 StandardError , 除非你打算重新觸發(fā)該異常, 或者你已經(jīng)在當(dāng)前線程的最外層(記得還是要打印一條錯(cuò)誤消息). 在異常這方面, Python非常寬容, except: 真的會捕獲包括Python語法錯(cuò)誤在內(nèi)的任何錯(cuò)誤. 使用 except: 很容易隱藏真正的bug。

盡量減少try/except塊中的代碼量. try塊的體積越大, 期望之外的異常就越容易被觸發(fā). 這種情況下, try/except塊將隱藏真正的錯(cuò)誤。

使用finally子句來執(zhí)行那些無論try塊中有沒有異常都應(yīng)該被執(zhí)行的代碼. 這對于清理資源常常很有用, 例如關(guān)閉文件。
當(dāng)捕獲異常時(shí), 使用 as 而不要用逗號. 例如    
try:
  raise Error
except Error as error:
  pass
設(shè)計(jì)實(shí)驗(yàn)方式

采取比較簡單直觀的對照實(shí)驗(yàn)。

先定義一個(gè)裝飾器,用來計(jì)算每個(gè)函數(shù)執(zhí)行所需時(shí)間:    
def timer(func):
  import time
  def wrapper(*args, **kwargs):
    startTime = time.time()
    f = func(*args, **kwargs)
    endTime = time.time()
    passTime = endTime - startTime
    print "執(zhí)行函數(shù)%s使用了%f秒" % (getattr(func, "__name__"), passTime)
    return f
  return wrapper

然后用該裝飾器裝飾測試的函數(shù)即可。

再定義一個(gè)叫do_something的函數(shù),這個(gè)函數(shù)中就做一件事,把1賦值給變量a。在每個(gè)測試函數(shù)中,都會調(diào)用這個(gè)函數(shù)1000000次。

do_something:    
def do_something():
  a = 1

我根據(jù)情況設(shè)計(jì)了不同的測試組:

測試組1(直接執(zhí)行耗時(shí)操作):    
@timer
def test1():
  for _ in xrange(1000000):
    do_something()

測試組2(耗時(shí)操作放在try中執(zhí)行,不拋出錯(cuò)誤):    
@timer
def test2():
  try:
    for _ in xrange(1000000):
      do_something()
  except Exception:
    do_something()
  else:
    pass
  finally:
    pass

測試組3(try放耗時(shí)操作中,try每一次操作,不拋出錯(cuò)誤):    
@timer
def test3():
  for _ in xrange(1000000):
    try:
      do_something()
    except Exception:
      do_something()
    else:
      pass
    finally:
      pass

測試組4(try放耗時(shí)操作中,try每一次操作并進(jìn)行異常處理(捕捉拋出的特定異常)):    
@timer
def test4():
  zero = 0
  for _ in xrange(1000000):
    try:
      if zero == 0:
        raise ZeroDivisionError
    except ZeroDivisionError:
      do_something()
    else:
      pass
    finally:
      pass

測試組5(try放耗時(shí)操作中,try每一次操作并進(jìn)行異常處理(捕捉所有異常 try…except BaseException)):    
@timer
def test5():
  zero = 0
  for _ in xrange(1000000):
    try:
      if zero == 0:
        raise ZeroDivisionError
    except BaseException:
      do_something()
    else:
      pass
    finally:
      pass

測試組6(try放耗時(shí)操作中,try每一次操作并進(jìn)行異常處理(捕捉所有異常 不帶任何異常類型)):    
@timer
def test6():
  zero = 0
  for _ in xrange(1000000):
    try:
      if zero == 0:
        raise ZeroDivisionError
    except:
      do_something()
    else:
      pass
    finally:
      pass

測試組7(耗時(shí)操作放在except中):    
@timer
def test7():
  zero = 0
  try:
    if zero == 0:
      raise ZeroDivisionError
  except ZeroDivisionError:
    for _ in xrange(1000000):
      do_something()
  else:
    pass
  finally:
    pass

測試組8(防御式編碼):    
@timer
def test8():
  zero = 0
  for _ in xrange(1000000):
    if zero == 0:
      do_something()
執(zhí)行結(jié)果

對比結(jié)論

通過對比1和2,可以得知直接執(zhí)行耗時(shí)操作和耗時(shí)操作放在try中執(zhí)行并無異常觸發(fā)時(shí)性能消耗幾乎是一樣的。

通過對比2和7,可以得知使用異常的使用無論是把代碼放在 try 中執(zhí)行還是在 except 中執(zhí)行性能消耗幾乎是一樣的。
    通過對比2和3,可以得知當(dāng)不拋出錯(cuò)誤時(shí),把try放耗時(shí)操作中比耗時(shí)操作放在try中性能消耗要略大。
    通過對比3和4,可以得知當(dāng)使用try時(shí)無異常拋出跟使用try時(shí)拋出異常性能消耗幾乎相差好幾倍。
    通過對比4和5,可以得知try放耗時(shí)操作中時(shí),try每一次操作并進(jìn)行異常處理(捕捉拋出的特定異常)跟try每一次操作并進(jìn)行異常處理(捕捉所有異常 try…except BaseException)性能消耗幾乎是一樣的。
    通過對比4和8,可以得知使用防御性方式編碼比捕捉異常方式性能消耗幾乎相差好幾倍。
    通過對比5和6,可以得知捕捉所有異常(try…except)方式比捕捉所有異常(try…except BaseException)方式要略快。
總結(jié)
    由以上對比結(jié)論,可以總結(jié)為:
    無論是把代碼放在 try 中執(zhí)行還是在 except 中執(zhí)行性能消耗幾乎是一樣的。
    直接執(zhí)行代碼與放在try中執(zhí)行且不拋出異常時(shí)性能消耗幾乎是一樣的,當(dāng)然理論上try會消耗一點(diǎn)性能,可以忽略不計(jì)。
    雖然try…except的方式比try…except BaseException和捕捉拋出的特定異常的方式要略快,但扔不建議采取這種方式,因?yàn)榍罢吆苋菀纂[藏真正的bug,從而帶來嚴(yán)重后果。
    通常要采取捕捉拋出的特定異常而不是捕捉所有異常,雖然二者性能消耗幾乎一樣。
    防御性方式編碼比捕捉異常方式性能消耗幾乎相差好幾倍,應(yīng)盡量采取這種編程方式,提升性能并且更靠譜。
以上就是本文關(guān)于Python異常對代碼運(yùn)行性能的影響實(shí)例解析的全部內(nèi)容,希望對大家有所幫助。

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }