The impact of Python exceptions on code running performance.

Source: Internet
Author: User

The impact of Python exceptions on code running performance.
Preface

The exception handling capability of Python is very powerful, but poor use may also bring negative effects. I usually like to use exceptions when writing programs. Although it is better to adopt a defensive encoding method, It will be lazy to handle exceptions. Occasionally, I think about the impact of exception handling on performance, so I tried to test it today.

Python exception (Google open-source Style Guide) tip:

Exceptions are allowed, but be careful.

Definition:

Exception is a way to jump out of the normal control flow of the code block to handle errors or other exception conditions.

Advantages:

The control flow of the normal operation code is not mixed with the error handling code. when a condition occurs, it also allows the control flow to skip multiple frameworks. for example, jump out of N nested functions in one step without executing the wrong code.

Disadvantages:

This may lead to confusing control flow. errors are easily missed when you call a database.

Conclusion:

Exceptions must comply with the following conditions:

An exception is triggered like this:raise MyException("Error message") Or raise MyException . Do not use the form of two parameters (raise MyException, "Error message") Or an out-of-date string exception (raise "Error message").
The module or package should define the Exception base class for its specific domain. This base class should inherit from the built-in Exception class. The Exception base class of the module should be called "Error ".

class Error(Exception):  pass 

Never useexcept: To capture all exceptions, do not captureExceptionOrStandardError Unless you want to re-trigger this exception, or you are already at the outermost layer of the current thread (remember to print an error message). In terms of exceptions, Python is very tolerant, except: It will really capture any errors, including Python syntax errors. Use bugs: it is easy to hide real bugs.

Minimize the amount of code in the try/try t block. The larger the size of the try block, the more likely the exception is to be triggered. In this case, try/try t block will hide the real error.

Use the finally clause to execute code that should be executed no matter whether exceptions exist in the try block. This is often useful for clearing resources, such as closing files.
When exceptions are caught, use as instead of commas. For example:

try:  raise Errorexcept Error as error:  pass
Design Lab Methods

The comparison experiment is simple and intuitive.

First define a decorator to calculate the time required for each function execution:

Def timer (func): import time def wrapper (* args, ** kwargs): startTime = time. time () f = func (* args, ** kwargs) endTime = time. time () passTime = endTime-startTime print "% s used for executing function % f seconds" % (getattr (func, "_ name _"), passTime) return f return wrapper

Then, use the decorator to decorate the test function.

Define another function called do_something. In this function, assign 1 to variable. In each test function, this function is called 1000000 times.

Do_something:

def do_something():  a = 1

I designed different test groups as needed:

Test Group 1 (directly perform time-consuming operations ):

@timerdef test1():  for _ in xrange(1000000):    do_something()

Test Group 2 (time-consuming operations are executed in try without throwing an error ):

@timerdef test2():  try:    for _ in xrange(1000000):      do_something()  except Exception:    do_something()  else:    pass  finally:    pass

Test Group 3 (in the try time-consuming operation, do not throw an error for each try operation ):

@timerdef test3():  for _ in xrange(1000000):    try:      do_something()    except Exception:      do_something()    else:      pass    finally:      pass

Test Group 4 (during the time-consuming try operation, try each operation and perform Exception Handling (capture specific exceptions thrown )):

@timerdef test4():  zero = 0  for _ in xrange(1000000):    try:      if zero == 0:        raise ZeroDivisionError    except ZeroDivisionError:      do_something()    else:      pass    finally:      pass

Test Group 5 (try time-consuming operations, try each operation and handle exceptions (capture all exceptions try... Failed t BaseException )):

@timerdef test5():  zero = 0  for _ in xrange(1000000):    try:      if zero == 0:        raise ZeroDivisionError    except BaseException:      do_something()    else:      pass    finally:      pass

Test Group 6 (try time-consuming operations, try each operation and handle exceptions (capture all exceptions without any exception types )):

@timerdef test6():  zero = 0  for _ in xrange(1000000):    try:      if zero == 0:        raise ZeroDivisionError    except:      do_something()    else:      pass    finally:      pass

Test Group 7 (time-consuming operations are placed in release T ):

@timerdef test7():  zero = 0  try:    if zero == 0:      raise ZeroDivisionError  except ZeroDivisionError:    for _ in xrange(1000000):      do_something()  else:    pass  finally:    pass

Test Group 8 (defensive encoding ):

@timerdef test8():  zero = 0  for _ in xrange(1000000):    if zero == 0:      do_something()

Execution result

Comparison conclusion
  • By comparing 1 and 2, we can know that the performance consumption is almost the same when the time-consuming operations and time-consuming operations are directly executed in try.
  • By comparing 2 and 7, we can know that the performance consumption of abnormal use is almost the same whether it is to put the code in try or in commit T.
  • By comparing 2 and 3, we can know that when no error is thrown, the performance consumption of time-consuming try operations is slightly higher than that of time-consuming try operations.
  • By comparing 3 and 4, we can know that the performance consumption of no exception throws when using try is almost several times different from that when using try.
  • By comparing steps 4 and 5, we can know that during the time-consuming try operation, try each operation and perform Exception Handling (capture the specific exceptions thrown) and try each operation and perform Exception Handling (catch all exceptions try... Except t BaseException) the performance consumption is almost the same.
  • By comparing 4 and 8, we can know that the performance consumption by using defensive encoding is almost several times different than that of capturing exceptions.
  • By comparing 5 and 6, we can know that all exceptions are caught (try... Faster than capturing all exceptions (try... Except t BaseException.
Summary
  1. The above comparison conclusions can be summarized:
  2. The performance consumption is almost the same whether the code is executed in a try or in the retry T.
  3. The performance consumption of direct code execution is almost the same as that of execution in try without throwing an exception. Of course, in theory, try consumes a little performance and can be ignored.
  4. Although try... Faster t than try... Except t BaseException and the method for capturing specific exceptions thrown should be slightly faster, but this method is not recommended because the former can easily hide real bugs and cause serious consequences.
  5. It is usually necessary to capture the specific exceptions thrown rather than all exceptions, although the performance consumption of the two is almost the same.
  6. Defensive encoding methods consume almost several times the performance compared to capturing exceptions. This programming method should be adopted as much as possible to improve performance and be more reliable.

The above is all about the impact of Python exceptions on code running performance on instance parsing. I hope it will be helpful to you. If you are interested, you can continue to refer to other related topics on this site. If you have any shortcomings, please leave a message. Thank you for your support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.