`
jeffreydan
  • 浏览: 26801 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

python异常处理对性能影响怎么样?

阅读更多

一、糟糕的代码

在使用python编程语言处理查找列表或字典中的某个数据项时,我经常看到这样的代码(省略具体逻辑):

场景一:
try:
    data_list = find("condition")[0]
except:
    pass

场景二:
try:
    dict_list = find("condition")["key"]
except:
    pass

 以上这些代码虽然能够满足程序的功能,但这都不是最佳的实现方式,原因如下:
1、try捕获异常会造成异常(软中断),会影响性能。
2、作为靠谱的程序员,应该采取防御性的方式编码,而不应该将错误的处理都丢给系统。

二、糟糕的代码执行时间上的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)

 观察上面的采样结果得知:
一、程序执行时间随着执行的次数同比递增增长。
二、其中使用try...except,Exception的方式会比使用try...except的方式稍花时间,但这点时间可以忽略不计。
三、其中当使用try方式时发生异常比使用try方式时无异常花费时间约10倍。
四、使用防御性方式编码在这几种方式中最花费时间最少。

三、总结

以上数据会根据程序执行环境的不同而得出不同的采样结果,从上面的采样数据结果来看,执行次数在10,000,000级别时候才有明显的延时,抛开性能影 响的层面,作为靠谱的程序员,应该采取防御性的方式编码,而不应该将错误的处理都丢给系统,这样的好处明显就是性能的提升,同时也加强了程序的可读性。

分享到:
评论
1 楼 marlonyao 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中小很多。

相关推荐

    Python异常对代码运行性能的影响实例解析

    偶尔会想想异常处理会对性能造成多大的影响,于是今天就试着测试了一下。 Python异常(谷歌开源风格指南) tip: 允许使用异常, 但必须小心。 定义: 异常是一种跳出代码块的正常控制流来处理错误或者其它异常条件的...

    Head First Python、Python核心编程

    你会迅速掌握Python的基础知识,然后转向持久存储、异常处理、Web开发、SQLite、数据加工和lGoogle App Engine。你还将学习如何为Android编写移动应用,这都要归功于Python为你赋予的强大能力。本书会提供充分并且...

    Python研究 从新手到高手 Dive Into Python 中文版

    18.性能优化">Python 从新手到高手 Dive Into Python 是为有经验的程序员编写的一本 Python 书。 1.在多个平台安装Python 2.第一个Python程序 3.内置数据类型 4.自省的威力 5.对象和面向对象 6.异常和文件处理 7....

    python入门学习资料

    第 6 章 异常和文件处理 第 7 章 正则表达式 第 8 章 HTML 处理 第 9 章 XML 处理 第 10 章 脚本和流 第 11 章 HTTP Web 服务 第 12 章 SOAP Web 服务 第 13 章 单元测试 第 14 章 测试优先编程 第 15 章 重构 第 16...

    老王Python基础+进阶+项目篇(高清无密)

    进阶篇16-异常处理1.2 进阶篇17-异常处理1.3 进阶篇18-周末异常习题探讨 进阶篇19-多线程1.1 进阶篇20-多线程1.2 进阶篇21-多线程1.3 进阶篇22-习题讲解复习 进阶篇23-用协程解决相关问题 进阶篇24-正则表达式1.1 ...

    老男孩python 四期

    5、异常处理,try….except 6、自定义异常类 7、Python函数概念、语法 8、函数参数 10、函数处理多个参数、默认参数 11、Return 12、正则表达式 13、迭代器和生成器 14、lambda 函数使用 15、装饰器 16、项目实践:...

    python知识点总结

    4. 文件操作:读取和写入文件,处理文件内容和路径,以及异常处理。 5. 面向对象编程:类、对象、继承、多态等面向对象编程的概念和实践。 6. 异步编程:使用协程和异步库进行异步编程,提高程序的并发性能。 7. ...

    Python 中文手册

    8.3. 异常处理 8.4. 抛出异常 8.5. 用户自定义异常 8.6. 定义清理行为 8.7. 预定义清理行为 9. 类 9.1. 术语相关 9.2. Python 作用域和命名空间 9.2.1. 作用域和命名空间示例 9.3. 初识类 9.3.1. 类定义语法 9.3.2. ...

    Python数据分析与挖掘实战学习笔记(3).md

    数据清洗主要介绍了对缺失值和异常值的处理,延续了第三章的缺失值和异常值分析的内容,本章主要介绍的处理缺失值的方法分为3类:删除记录、数据插补和不处理,处理异常值的方法有删除含有异常值的记录、不处理、...

    python 工程师技能图谱

    理解异常处理机制,编写健壮的代码。 2. 编程范式: 掌握面向对象编程(OOP)的概念,能够设计和实现类、继承、多态等。 理解函数式编程(FP)的基本原则,熟悉Lambda函数、高阶函数等。 3. 标准库和第三方库: ...

    python cookbook(第3版)

    14.6 处理多个异常 14.7 捕获所有异常 14.8 创建自定义异常 14.9 捕获异常后抛出另外的异常 14.10 重新抛出最后的异常 14.11 输出警告信息 14.12 调试基本的程序崩溃错误 14.13 给你的程序做基准测试 14.14...

    《Python编程金典》读书笔记

    12. 异常处理 12.1. 知识点 12.2. 良好的编程习惯 12.3. 常见编程错误 12.4. 测试和调试提示 12.5. 软件工程知识 12.6. 性能提示 13. 字符串处理和正则表达式 13.1. 知识点 13.2. 良好的编程习惯 13.3. 性能提示 14....

    MySQL MTOP是一个由Python+PHP开发的开源MySQL数据库监控系统

    并能在数据库偏离设定的正常运行阀值(如连接异常,复制异常,复制延迟) 时发送告警邮件通知到DBA进行处理。并对历史数据归档,通过图表展示出数据库近期状态,以便DBA和开发人员能对遇到的问题进行分析和诊断。

    安居客二手房爬虫加数据分析加报告 python

    在数据预处理阶段,我们对数据进行了清洗和转换,包括缺失值处理、异常值处理、重复值处理以及特征工程等操作。在数据可视化阶段,我们通过散点图、箱线图、相关系数矩阵热力图等方式,分析了不同属性之间的关系。在...

    dive into python

    6.1. 异常处理 6.1.1. 为其他用途使用异常 6.2. 与文件对象共事 6.2.1. 读取文件 6.2.2. 关闭文件 6.2.3. 处理 I/O 错误 6.2.4. 写入文件 6.3. for 循环 6.4. 使用 sys.modules 6.5. 与目录共事 6.6. 全部...

    python进阶篇共34集

    在学习python基础后,适合想要学习...6、异常处理 7、多线程 8、用协程解决相关问题 9、正则表达式 10、socket网络通信 11、高性能的多线程网络资源访问 12、http讲解 13、wsgi讲解 14、进阶项目实战练习 15、项目讲解

    MILOF:HPC性能数据的在线异常检测

    HPC性能数据的在线异常检测该库提供了一个Python API,用于处理 (科学工作流的可伸缩观察系统)性能跟踪。 它支持以下功能: 流事件解析器:通过兴趣函数动态传递SOSflow事件流异常检测器:基于有限内存增量局部...

    md格式编写的良心教程 Python 100天从新手到大师 共100个完整源文件 含课程源代码.rar

    文件和异常.md Day01-15\12.字符串和正则表达式.md Day01-15\13.进程和线程.md Day01-15\14.网络编程入门和网络应用开发.md Day01-15\15.图像和办公文档处理.md Day16-20\16-20.Python语言进阶.md Day21-30\21-30....

Global site tag (gtag.js) - Google Analytics