2011-01-17 12 views
21

Tengo metido en la cabeza que (al menos en PHP) es badbadmojo usar try... catch bloques para control de flujo. Lo que he aprendido es usarlos solo para manejar errores inesperados, no determinar el flujo lógico del programa, porque los bloques catch son caros.¿El manejo de excepciones de python es más eficiente que PHP u otros lenguajes?

Ahora que estoy aprendiendo Python, veo muchas excepciones en todas partes y el principio EAFP. ¿Esto significa que Python es más eficiente en el manejo de excepciones, por lo que no es necesario que esté tan preocupado por el control de flujo, o el principio sigue en pie? Si no, ¿PHP es la excepción de la norma (en comparación con otros lenguajes) o es Python?

+1

C++ es similar a PHP en lo que respecta a las excepciones (al menos para las aplicaciones de escritorio; las incrustadas pueden ser diferentes) - las excepciones generadas ** realmente ** perjudican su rendimiento. – Zooba

+0

El rendimiento de C# también se degrada gravemente cuando se lanzan excepciones. –

+1

Acabo de dar cuenta de que escribí "excepción de la norma". Por favor, no lo tome como un mal juego de palabras X-P – keithjgrant

Respuesta

13

Históricamente, en lenguajes como C++, las excepciones han sido muy lento en comparación con otra formas de control de flujo en el mismo idioma.

En C++, hay dos cosas en el trabajo:

  • lanzar una excepción es muy complejo. La pila necesita ser desenrollada, y hacerlo en código nativo es mucho más difícil que en un lenguaje de VM de alto nivel.
  • El control de flujo directo regular es extremadamente rápido. Es un código nativo; una bifurcación es un par de instrucciones, donde una excepción al retroceder la pila invoca un algoritmo complejo (buscar datos de la pila en una tabla grande, posiblemente comprimida, y así sucesivamente).

Esta disparidad en el rendimiento condujo a la sabiduría general detrás de las excepciones: solo hágalo para cosas inusuales, por lo que solo se usa donde sea más beneficioso y no donde afecte el rendimiento.

Esto no se aplica a los idiomas de alto nivel. Esto también se debe a dos razones:

  • Revertir la pila es mucho, mucho más simple.La pila es muy fácil de examinar; no necesita tablas mágicas para saber hasta qué punto revertir la pila y qué objetos se construyen en un momento dado.
  • El flujo de programa regular es inherentemente más lento. En un lenguaje basado en VM, todo simplemente requiere más trabajo para empezar.

Las excepciones aún no son gratuitas, pero la disparidad ya no es algo de lo que preocuparse. Esto significa que la sabiduría general formada en C++ se aplica mal aquí. Las excepciones se usan regularmente en el flujo normal del programa.

De hecho, están integrados en el lenguaje, en construcciones que utiliza todo el tiempo. Cada vez que utiliza un iterador, cada for x in xrange(1000), se utiliza una excepción StopIteration para finalizar el ciclo.

Elija excepciones o control de flujo lineal en Python en función del cual tenga más sentido. No elija en función del rendimiento, a menos que se encuentre en un bucle interno donde el rendimiento importa; en ese caso, como siempre, haga un perfil y descubra si realmente importa.

(no puedo hablar por PHP.)

7

No creo que el EAFP aliente el uso de excepciones para el control de flujo. Por el contrario, nos dice que no debemos molestarnos en verificar la existencia de una clave en particular en un diccionario o propiedad de un objeto antes de hacer referencia a ella.

lanzar excepciones como una alternativa a if declaraciones o tener while afirmaciones correctas o en lugar de utilizar break o continue dentro de un bucle no se incluye en esa categoría. Eso es un programa lento, propenso a errores y debe evitarse.

0

Hay una excepción específica que sólo se supone que se utilizará en el flujo de ejecución normal: StopIteration. Esto implica para mí que el creador de Python no cree que la sobrecarga de excepción esté fuera de línea.

si esto se debe a que el manejo de excepciones es súper-eficiente o el resto de la lengua es simplemente lento en comparación, es otra cuestión ...

2

Para responder a la pregunta: Si. Las excepciones de Python son baratas. Una prueba if es aún más económica, así que sí, debería usar excepciones para situaciones "inesperadas", en la medida en que si espera que el código falle la mayoría de las veces, verifique antes de hacerlo. Dado que el if-check evitará también el intento real, así como el aumento y la captura de la excepción, eso será mucho más rápido en una situación que falla. (A menos que, por supuesto, la prueba en sí misma sea costosa).

Pero no tiene sentido evitar excepciones como tales. Python no se arrastrará a un rastreo porque se detectan muchas excepciones.

Y como de costumbre: la optimización sin perfilado es prematura.

0

He leído un poco más, y me he dado cuenta de otra cosa importante que nadie ha mencionado aún: en Python, no hay distinción entre Errores y Excepciones. Sabía esto, pero no creo haber captado el significado hasta ahora.

En PHP, se puede envolver en $page->GetContent();try...catch bloquea todos los que quieran, pero si $page no es un objeto, su aplicación todavía se llega a un alto con el error fatal resultante. Por lo tanto, en PHP (y en cualquier otro idioma donde no se puedan detectar errores), usted necesita un cierto nivel de LBYL.

Python básicamente dice: "eso es estúpido, debería ser capaz de atraparlos". Simplemente intente hacer lo que necesita hacer y lidiar con las consecuencias en el bloque except.

Aquí hay un great article on exception handling que encontré.

Cuestiones relacionadas