python异常处理对性能影响怎么样?
一、糟糕的代码
在使用python编程语言处理查找列表或字典中的某个数据项时,我经常看到这样的代码(省略具体逻辑):
场景一:try: data_list = find("condition")[0]except: pass场景二:try: dict_list = find("condition")["key"]except: pass
?以上这些代码虽然能够满足程序的功能,但这都不是最佳的实现方式,原因如下:
1、try捕获异常会造成异常(软中断),会影响性能。
2、作为靠谱的程序员,应该采取防御性的方式编码,而不应该将错误的处理都丢给系统。
基于上述原因,我与编码者(上述代码作者)交流过,其中的回答“python对异常的处理方式非常好,从而几乎不影响性能,这也是推荐的一种处理方式”让我好奇,于是做了个小实验---python异常处理对性能的有多大的影响?源代码如下:
#! /bin/usr/env python# -*- coding:utf-8 -*-import time#统计方法执行的时间def count_time(func): def wrap(*args): start = time.time() func(*args) end = time.time() print "func:%s time:(%0.3f ms)" % (func.func_name, (end-start) * 1000) return wrap#key不存在的时候@count_timedef not_exists_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["not_exists"] except: pass#key存在的时候@count_timedef exists_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["do_something"] except: pass#key不存在的时候并使用Exception@count_timedef not_exists_use_try_except(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["not_exists"] except Exception, e: pass#key存在的时候并使用Exception@count_timedef exists_use_try_except(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["do_something"] except Exception, e: pass#使用防御性编码@count_timedef not_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): if "not_exists" in dict_list : pass else: passdef run(max): print "max:%s" % max not_exists_use_try(max) not_exists_use_try_except(max) exists_use_try(max) exists_use_try_except(max) not_use_try(max)if __name__ == "__main__":#100 run(100)#1,000 run(1000)#10,000 run(10000)#100,000 run(100000)#1,000,000 run(1000000)#10,000,000 run(10000000)
?通过对上面的实验程序的3次运行,采样结果如下:
max:100func:not_exists_use_try time:(0.110 ms)func:not_exists_use_try_except time:(0.110 ms)func:exists_use_try time:(0.012 ms)func:exists_use_try_except time:(0.011 ms)func:not_use_try time:(0.009 ms)max:1,000func:not_exists_use_try time:(0.941 ms)func:not_exists_use_try_except time:(1.058 ms)func:exists_use_try time:(0.091 ms)func:exists_use_try_except time:(0.091 ms)func:not_use_try time:(0.063 ms)max:10,000func:not_exists_use_try time:(10.341 ms)func:not_exists_use_try_except time:(10.869 ms)func:exists_use_try time:(0.879 ms)func:exists_use_try_except time:(0.904 ms)func:not_use_try time:(0.616 ms)max:100,000func:not_exists_use_try time:(95.245 ms)func:not_exists_use_try_except time:(109.051 ms)func:exists_use_try time:(9.277 ms)func:exists_use_try_except time:(9.290 ms)func:not_use_try time:(7.086 ms)max:1,000,000func:not_exists_use_try time:(932.254 ms)func:not_exists_use_try_except time:(1088.768 ms)func:exists_use_try time:(110.238 ms)func:exists_use_try_except time:(104.085 ms)func:not_use_try time:(85.284 ms)max:10,000,000func:not_exists_use_try time:(9292.667 ms)func:not_exists_use_try_except time:(10858.698 ms)func:exists_use_try time:(1037.037 ms)func:exists_use_try_except time:(1008.167 ms)func:not_use_try time:(812.829 ms)
?观察上面的采样结果得知:
一、程序执行时间随着执行的次数同比递增增长。
二、其中使用try...except,Exception的方式会比使用try...except的方式稍花时间,但这点时间可以忽略不计。
三、其中当使用try方式时发生异常比使用try方式时无异常花费时间约10倍。
四、使用防御性方式编码在这几种方式中最花费时间最少。
以上数据会根据程序执行环境的不同而得出不同的采样结果,从上面的采样数据结果来看,执行次数在10,000,000级别时候才有明显的延时,抛开性能影响的层面,作为靠谱的程序员,应该采取防御性的方式编码,而不应该将错误的处理都丢给系统,这样的好处明显就是性能的提升,同时也加强了程序的可读性。
@count_timedef exists_not_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): if "do_something" in dict_list : dict_list["do_something"] else: pass