Python速度测试 - 除了失败之外,为什么花费这么多时间

Col*_*ole 0 python

我假设try/except工作流比if/then工作流更快,因为简单的操作'尝试从list_l中删除x'.在下面的示例中,除了失败(x不在list_l中)的成本比权限请求(如果x在list_l中)的成本更高,即使异常的可能性是16.6%.为什么?

以下是我编码的测试及其结果:

import random, time, timeit

class Timer(object):
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, *args):
        self.end = time.time()
        self.secs = self.end - self.start
        self.msecs = self.secs * 1000  # millisecs

def a_function():
    a_list = list(xrange(10))
    choice_list = list(xrange(12))
    choice = random.choice(choice_list)
    try:
        a_list.remove(choice)

    except ValueError:
        pass

def b_function():
    a_list = list(xrange(10))
    choice_list = list(xrange(12))
    choice = random.choice(choice_list)
    if choice in a_list:
        a_list.remove(choice)

with Timer() as a:
    print('test_a', timeit.timeit("a_function()", number=10000, setup="from __main__ import a_function"))

with Timer() as b:
    print('test_b', timeit.timeit("b_function()", number=10000, setup="from __main__ import b_function"))
Run Code Online (Sandbox Code Playgroud)

结果:

1st attempt: ('test_a', 0.029724836349487305)('test_b', 0.027068138122558594)

2nd attempt: ('test_a', 0.02960801124572754)('test_b', 0.026785850524902344)

3rd attempt: ('test_a', 0.029654979705810547)('test_b', 0.02665996551513672)

此外,如果我将choice_list范围增加到20,则差异会扩大,因为异常会更频繁地发生.如果python强烈请求宽恕 - 不允许,为什么失败似乎在时间方面花费了很多?

Lin*_*ios 6

任何语言的例外都是非常昂贵的,这是对它们的误用.

例外情况是指您的代码无法解释的特殊情况,并且在正常操作期间不会出现这种情况.不同的语言对于什么是异常具有不同的规则,但是16%的时间发生的事情并不罕见,只是不寻常.

异常是昂贵的,因为它们涉及堆栈展开和跳转,暂停正常处理以及搜索处理程序.if/then是标准的,正常的条件,有效且清晰.

  • 虽然我原则上同意你的观点,但在Python中,强烈建议用户在其他语言使用`if ... then`子句的许多情况下使用`try ... except`结构.虽然它的计算效率不高,但在语义上有效(在Python中)使用异常将某些类型的消息传递到调用堆栈.由于Python中鼓励的"鸭子打字"范式,尤其如此. (7认同)
  • 有趣的背景:http://www.jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/ (2认同)