浏览 6648 次
锁定老帖子 主题:python异常处理对性能影响怎么样?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-19
最后修改:2011-01-19
一、糟糕的代码在使用python编程语言处理查找列表或字典中的某个数据项时,我经常看到这样的代码(省略具体逻辑): 场景一: try: data_list = find("condition")[0] except: pass 场景二: try: dict_list = find("condition")["key"] except: pass 以上这些代码虽然能够满足程序的功能,但这都不是最佳的实现方式,原因如下: 二、糟糕的代码执行时间上的PK基于上述原因,我与编码者(上述代码作者)交流过,其中的回答“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_time def not_exists_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["not_exists"] except: pass #key存在的时候 @count_time def exists_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): try: dict_list["do_something"] except: pass #key不存在的时候并使用Exception @count_time def 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_time def 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_time def not_use_try(max): dict_list = {"do_something":"...."} for item in range(0, max): if "not_exists" in dict_list : pass else: pass def 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:100 func: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,000 func: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,000 func: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,000 func: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,000 func: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,000 func: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) 观察上面的采样结果得知: 三、总结以上数据会根据程序执行环境的不同而得出不同的采样结果,从上面的采样数据结果来看,执行次数在10,000,000级别时候才有明显的延时,抛开性能影 响的层面,作为靠谱的程序员,应该采取防御性的方式编码,而不应该将错误的处理都丢给系统,这样的好处明显就是性能的提升,同时也加强了程序的可读性。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-01-19
你的测试不公平,你应当至少还加上一种测试情况:
@count_time def 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 这里做了两次判断,在我的机器上,它比exists_use_try和exists_use_try_except都慢。 从性能上来说,如果key存在的情况是大多数情况,用try except可能速度更快。 其实速度根本相差无几,可读性才重要。在python中,另一种方法是使用get。我也同意你的观点,应当使用防御性编程,可能是因为我之前是写java的,在java中创建异常会同时创建stacktrace,这是很耗时的操作,在python中异常是不带stacktrace(在python中叫做traceback)的,所以创建异常的开销比java中小很多。 |
|
返回顶楼 | |