【问题标题】:Is python exception handling more efficient than PHP and/or other languages?python 异常处理是否比 PHP 和/或其他语言更有效?
【发布时间】:2011-06-10 16:32:56
【问题描述】:

我已经深入到我的脑海中(至少在 PHP 中)使用try... catch 块进行流控制是很糟糕的。我学到的只是使用它们来处理意外错误,而不是确定程序的逻辑流程,因为catch 块很昂贵。

现在我正在学习 python,我看到到处都有很多异常和EAFP 原则。这是否意味着python在处理异常方面效率更高,所以我不需要为流量控制而担心它们,还是原理仍然成立?如果不是,PHP 是规范的例外(与其他语言相比),还是 Python?

【问题讨论】:

  • C++ 在异常方面类似于 PHP(至少对于桌面应用程序 - 嵌入式可能不同) - 抛出的异常真的会损害您的性能。
  • C# 的性能在抛出异常时也会严重下降。
  • 刚刚意识到我输入了“规范中的例外”。请不要把它当作一个糟糕的双关语X-P

标签: php python exception programming-languages


【解决方案1】:

从历史上看,在 C++ 等语言中,与其他形式的流控制相比,异常在同一语言中的速度非常慢

在 C++ 中,有两件事在起作用:

  • 引发异常非常复杂。堆栈需要展开,在本机代码中这样做比在基于 VM 的高级语言中要困难得多。
  • 定期、直接的流量控制非常快。它是本机代码;分支是一对指令,其中回滚堆栈的异常会调用复杂的算法(在可能是压缩的大型表中查找堆栈数据等)。

这种性能差异导致了例外背后的普遍智慧:只为不寻常的事情做,所以它只用于最有益的地方,而不是会损害性能的地方。

这不适用于高级语言。这也有两个原因:

  • 回滚堆栈要简单得多。堆栈很容易检查;您不需要魔术表就可以知道回滚堆栈的距离以及在任何给定时间构造了哪些对象。
  • 常规程序流程本质上较慢。在基于 VM 的语言中,一切都需要更多的工作才能开始。

异常仍然不是免费的,但差异不再是值得担心的事情。这意味着在 C++ 中形成的一般智慧在这里被误用了。在正常的程序流程中经常使用异常。

事实上,它们是内置在语言中的,在你一直使用的结构中。每次使用迭代器时——每个for x in xrange(1000),都会使用StopIteration 异常来结束循环。

在 Python 中选择异常或线性流控制更有意义。不要根据性能进行选择,除非您实际上处于性能很重要的内部循环中;在这种情况下,一如既往地分析并找出它是否真的重要。

(我不会为 PHP 说话。)

【讨论】:

    【解决方案2】:

    我不认为 EAFP 鼓励使用异常来进行流控制。相反,它告诉我们,在引用它之前,我们不需要检查字典中的特定键或对象的属性是否存在。

    抛出异常作为if 语句的替代方法或具有正确的while 语句或在循环内使用breakcontinue 不属于该类别。这是一种懒惰、容易出错的编程,应该避免。

    【讨论】:

      【解决方案3】:

      伟大的 Alex Martelli 在“Python In A Nutshell”一书中对 EAFP 与 LBYL 进行了很好的概述。 (他非常倾向于使用 EAFP)

      def值得一读:
      http://books.google.com/books?id=JnR9hQA3SncC&lpg=PA134&ots=JaaWGy-24u&dq=alex%20martelli%20eafp%20lbyl&pg=PA134#v=onepage&q&f=false

      【讨论】:

      • +1 链接到 StackOverflower 写的一本书的非常有趣和授权的意见:)
      【解决方案4】:

      回答这个问题:是的。 Python 异常很便宜。 if 测试仍然更便宜,所以是的,您应该只在“意外”情况下使用异常,就像您希望代码大多数时候失败一样,请在执行之前检查。由于 if-check 还将避免实际尝试以及引发和捕获异常,因此在失败的情况下会快得多。 (当然,除非测试本身很昂贵)。

      但是避免这样的异常是没有意义的。 Python 不会拖拖拉拉,因为你会捕获很多异常。

      和往常一样:没有分析的优化还为时过早。

      【讨论】:

        【解决方案5】:

        有一个只应该在正常执行流程中使用的特定异常:StopIteration。这对我来说意味着 Python 的创建者并不认为异常开销是不合时宜的。

        这是因为异常处理效率超高,还是语言的其他部分比较慢,这是另一个问题...

        【讨论】:

          【解决方案6】:

          我已经阅读了更多内容,并意识到了另一件尚未有人提及的重要事情:在 Python 中,错误和异常之间没有区别。我知道这一点,但我想我直到现在才明白其中的意义。

          在 PHP 中,您可以将 $page->GetContent(); 包装到 try...catch 块中,但如果 $page 不是对象,您的应用程序仍会急速停止并导致致命错误。因此,在 PHP(以及任何其他无法捕获错误的语言)中,您需要一定级别的 LBYL。

          Python 基本上说,“这很愚蠢,我应该能够抓住那些。”只需尝试做您需要做的事情,并处理 except 块中的任何后果。

          这是我遇到的great article on exception handling

          【讨论】:

            猜你喜欢
            • 2014-09-15
            • 2014-11-03
            • 1970-01-01
            • 2022-01-13
            • 1970-01-01
            • 2013-10-25
            • 2014-07-14
            • 1970-01-01
            • 2016-06-05
            相关资源
            最近更新 更多