Supongamos que tengo una if
declaración con a return
. Desde la perspectiva de la eficiencia, ¿debería usar
if(A > B):
return A+1
return A-1
o
if(A > B):
return A+1
else:
return A-1
¿Debería preferir uno u otro al usar un lenguaje compilado (C) o uno con script (Python)?
python
c
performance
compiler-construction
Jorge Leitao
fuente
fuente
Respuestas:
Como la
return
declaración termina la ejecución de la función actual, las dos formas son equivalentes (aunque la segunda es posiblemente más legible que la primera).La eficiencia de ambas formas es comparable, el código de máquina subyacente debe realizar un salto si la
if
condición es falsa de todos modos.Tenga en cuenta que Python admite una sintaxis que le permite usar solo una
return
declaración en su caso:fuente
return (A>B)?A+1:A-1;
Sin embargo, no hay absolutamente ninguna ganancia en el rendimiento al escribir el código de esta manera. Todo lo que hemos logrado es hacer que el código sea ofuscado, ilegible y, en algunos casos, más vulnerable a las promociones de tipo implícito.<
es una mala práctica porque-1 < 1u
produce un resultado inesperado.-1 < 1u
, lo cual dudo, fácilmente detectarían el error. Sin embargo, mucha gente escribiría alguna versión del código que publiqué. He visto tales errores con demasiada frecuencia en el código de producción para confiar en el operador?:. Además, como regla general, si el idioma le ofrece dos formas diferentes de hacer lo mismo, solo use una de ellas, no elija ninguna de las dos al azar según su estado de ánimo.De la guía de estilo de Chromium :
No use más después del regreso:
fuente
if-else-return
ramas casi nunca son iguales (si lo son, entonces debería refactorizar de todos modos; ya sea usando unaswitch
construcción o para Python, enumerando un dict / usando un invocable / etc.). Por lo tanto, casi todosif-else-return
son casos de cláusulas de protección y siempre son comprobables (se burlan de la expresión probada) sin elelse
.En cuanto al estilo de codificación:
La mayoría de los estándares de codificación, sin importar el idioma, prohíben múltiples declaraciones de retorno de una sola función como mala práctica.
(Aunque personalmente diría que hay varios casos en los que las declaraciones de retorno múltiples tienen sentido: analizadores de protocolo de texto / datos, funciones con manejo extenso de errores, etc.)
El consenso de todos los estándares de codificación de la industria es que la expresión debe escribirse como:
En cuanto a la eficiencia:
El ejemplo anterior y los dos ejemplos en la pregunta son completamente equivalentes en términos de eficiencia. El código de máquina en todos estos casos tiene que comparar A> B, luego ramificarse con el cálculo A + 1 o A-1, luego almacenar el resultado de eso en un registro de CPU o en la pila.
EDITAR:
Fuentes:
fuente
return
donde sea que esté claro es la forma idiomática de hacerlo en Python.Con cualquier compilador sensato, no deberías observar ninguna diferencia; deben compilarse con un código de máquina idéntico ya que son equivalentes.
fuente
Esta es una cuestión de estilo (o preferencia) ya que al intérprete no le importa. Personalmente, trataría de no hacer la declaración final de una función que devuelve un valor en un nivel de sangría que no sea la base de la función. El otro en el ejemplo 1 oculta, aunque solo sea ligeramente, dónde está el final de la función.
Por preferencia yo uso:
Como obedece tanto la buena convención de tener una sola declaración de retorno como la última declaración en la función (como ya se mencionó) y el buen paradigma de programación funcional de evitar resultados intermedios de estilo imperativo.
Para funciones más complejas, prefiero dividir la función en múltiples subfunciones para evitar retornos prematuros si es posible. De lo contrario, vuelvo a usar una variable de estilo imperativa llamada rval. Intento no usar múltiples declaraciones de retorno a menos que la función sea trivial o la declaración de retorno antes del final sea como resultado de un error. Regresar prematuramente resalta el hecho de que no puedes continuar. Para funciones complejas que están diseñadas para ramificarse en múltiples subfunciones, trato de codificarlas como declaraciones de casos (impulsadas por un dict, por ejemplo).
Algunos carteles han mencionado la velocidad de operación. La velocidad del tiempo de ejecución es secundaria para mí, ya que si necesita velocidad de ejecución, Python no es el mejor lenguaje para usar. Utilizo Python como la eficacia de la codificación (es decir, escribir código libre de errores) lo que me importa.
fuente
var n = 1 if (A > B) else -1
return A+n
Yo personalmente evito los
else
bloqueos cuando sea posible. Ver la campaña anti-siAdemás, no cobran 'extra' por la línea, ya sabes: p
"Simple es mejor que complejo" y "La legibilidad es el rey"
fuente
dict
s para evitar diferencias es una muy mala idea en cuanto al rendimiento.La versión A es más simple y por eso la usaría.
Y si activa todas las advertencias del compilador en Java, recibirá una advertencia en la segunda versión porque es innecesaria y aumenta la complejidad del código.
fuente
Sé que la pregunta está etiquetada como python, pero menciona lenguajes dinámicos, así que pensé que debería mencionar que en ruby, la instrucción if tiene un tipo de retorno para que pueda hacer algo como
O porque también tiene un retorno implícito simplemente
que evita el problema del estilo de no tener múltiples retornos bastante bien.
fuente