2010-03-05 10 views
15

Este blog dice¿La adición de instrucciones de devolución para los métodos de C# mejora el rendimiento?

12) incluyen declaraciones de retorno con la función/método. Cómo mejora el rendimiento La utilización explícita del retorno permite que el JIT realice un poco más de optimizaciones. Sin una declaración de retorno, a cada función/método se le asignan varias variables locales en la pila para admitir de forma transparente los valores que regresan sin la palabra clave. Mantener estos valores hace que sea más difícil para el JIT optimizar, y puede afectar el rendimiento de su código. Mire a través de sus funciones/métodos e inserte el retorno según sea necesario. No cambia la semántica del código en absoluto, y puede ayudarte a obtener más velocidad de tu aplicación.

Estoy bastante seguro de que esta es una declaración falsa. Pero quería que los expertos en opinión salieran. ¿Qué piensan ustedes?

+4

Parece sospechoso, de hecho, ¡pero dejaré que los gurús JIT entren en peso! – mjv

+4

Hay más declaraciones sospechosas. "Usar 'ArrayLists' en lugar de matrices", "Diseñar con ValueTypes". Quiero decir, ArrayLists? Eso es genial con el boxeo. Y saber exactamente cuándo usar estructuras en lugar de clases es algo que muchas personas, si no la mayoría, se mezclan, incluyéndome a mí. Extraño "consejo". – Razzie

+0

En la línea de la observación de @ Razzie, me gustaría tomar esa publicación con un grano de sal, no toma en consideración los elementos agregados incluso en .NET 2.0 días .... –

Respuesta

10

Esta afirmación no se aplica a C#.

Con C# debe establecer explícitamente un "retorno" para tener una función válida, sin un retorno, obtendrá un error de compilación al efecto de "no todas las rutas de código devuelven un valor".

Con VB.NET esto se aplicaría ya que VB.NET NO tiene el requisito de una devolución explícita, y le permite tener funciones que nunca devuelven un valor, así como también le permite establecer la declaración utilizando el nombre de la función.

Para proporcionar un ejemplo

En VB.NET puede hacerlo

Function myFunction() As String 
    myFunction = "MyValue" 
End Function 

Function myFunction2() As String 
    'Your code here 
End Function 

Las compilaciones anteriores, ni con un explícitas "retornos", hay más sobrecarga involucrada en esto.

Si intenta hacer esto con C#

string myFunction() 
{ 
    //Error due to "Cannot assign to 'myFunction' because it is a 'Method Group' 
    myFunction = "test"; 
} 

string myFunction2() 
{ 
    //Error due to "not all code paths return a value 
} 

Los comentarios que tenga en cuenta los errores que se obtiene.

+0

... personalmente? – Svish

+0

Sí, eliminé eso ... ya ha pasado una mañana larga ... –

+0

Leí el texto citado de OP del blog en el sentido de usar declaraciones de retorno para procesar el cortocircuito, como en palabras de Nick. – chsh

1

Mi única conjetura es que él está hablando de que VB.NET no es C#. VB.NET le permite algo como esto para devolver los valores

Public Function GetSomething() As Int 
    GetSomething = 4 
End Function 

Mi VB está increíblemente desactualizado. Esto puede ser más lento que con una declaración de devolución explícita

+0

Además, esta publicación: http://stackoverflow.com/questions/451025/vb-net-function-return habla sobre el rendimiento y la declaración de devolución en VB.Net: el il generado parece casi el mismo ergo, la velocidad es la misma. (No hice un desmontaje, pero el que se presenta en esta pregunta parece lógico) –

+0

@dotjoe: ¿Cómo es eso? Esto es realmente bastante útil para casos en los que, en C#, tendría que declarar una variable de 'resultado' (o similar). Personalmente, he adaptado completamente el estilo C# pero no puedo formar un argumento convincente sobre por qué el estilo VB debería ser peor. Para mí, es simplemente una cuestión de hábito, y la forma de hacer esto de VB es perfectamente razonable. –

+0

@Konrad Rudolph espera ... ¿esta sintaxis no es lo mismo que 'Return 4'? ¿Tiene el resultado hasta el final de la función y se puede configurar varias veces? – dotjoe

4

La publicación es un poco vaga. Al ser un desarrollador de C#, mi primer pensamiento fue "¿en comparación con qué?". Sin embargo, podría estar refiriéndose a algo como:

public bool MyFunction() 
{ 
    bool result = false; 
    if (someCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    else if (someOtherCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    // ... keep going 

    return result; 
} 

Él puede estar sugiriendo que la sustitución de las declaraciones result = true; con return true; puede funcionar mejor. No estoy seguro de eso personalmente ... eso es bastante profundo en la teoría de JIT en ese momento, y creo que cualquier ganancia que se realice sería muy leve en comparación con otras mejoras de rendimiento que podría hacer.

+0

De acuerdo con esto: ¡es uno de esos momentos en los que debe decidir que la mantenibilidad es más importante que la insignificante ganancia de rendimiento! – Fenton

0

En general, hay 2 lugares en los que salgo de una función. En el comienzo de mis métodos para validar los datos de entrada:

if (myParameter == null) 
    throw new ArgumentNullException("myParameter"); 

y/o al final del método.


private bool GetSomeValue() 
{ 
    bool returnValue = false; 
    // some code here 
    if (some condition) 
    { 
     returnValue = some expression 
    } 
    else 
    { 
     returnValue = some other expression; 
    } 
    return returnValue; 
}

La razón por la que no regreso dentro de la condicional, es por lo que no hay punto 1 de la función de salida, que ayuda con la depuración. Nadie quiere tener que mantener un método con 12 declaraciones de retorno. Pero esa es solo una opinión personal mía. Yo me equivocaría por el lado de la legibilidad, y no me preocuparía la optimización a menos que se trate de una situación en tiempo real que debe irse más rápido.

+4

IMO, la noción del punto de retorno único es irrelevante en el software moderno. Prefiero ver de inmediato una declaración de devolución y saber que el código ha salido de tener que preguntarme si returnValue se manipula en otro lugar más abajo del método si pudieras haber regresado desde esos bloques. –

+1

@ChrisMarisic - Estoy de acuerdo. El argumento multiple-returns-is-bad agrega * noise * al código. Si tiene que regresar en 5 lugares, eso no puede ser peor que la bifurcación de 5 maneras hasta el final con el posible cambio de estado con el posible lector sin seguir el intento. – Kit

+0

@Kit Tuve que leer tu comentario un par de veces para asegurarme de haberlo entendido. Estoy de acuerdo con usted, la elección de retrasar el regreso cuando puede regresar inmediatamente ** ** agregará ruido al código. –

2

Es cierto tanto para VB.NET como para C#. En C# el programador tiene que declarar la variable que contiene el valor de retorno explícitamente, es automático en VB.NET. La mayoría de los valores devueltos se devuelven en el registro EAX o RAX, el compilador JIT debe generar código para cargar el registro de la variable de valor de retorno antes de que la función finalice. Cuando utiliza la declaración return, el compilador JIT puede tener la oportunidad de cargar el registro EAX directamente, o ya tener el registro que contiene el valor correcto, y saltar al código de salida de la función, pasando por alto la instrucción de cargar de la variable.

Esa es una gran "poderosa" por cierto, el código real invariablemente prueba algunas expresiones con la instrucción if(). La evaluación de esa expresión casi siempre implica el uso del registro EAX, todavía tiene que volver a cargarse con el valor de retorno. El compilador x64 JIT hace un trabajo completamente diferente haciendo eso en comparación con el compilador x86, este último siempre parece usar la variable en algunas comprobaciones puntuales que hice. Por lo tanto, no es probable que esté adelante a menos que ejecute una versión de Windows de 64 bits.

De todo el mal en la optimización prematura, este es posiblemente el peor. El ahorro de tiempo potencial es minúsculo, primero escriba su código para mayor claridad. Perfil más tarde.

+0

Hay un caso en que la sintaxis de retorno simplifica para el compilador su optimización de recursión de llamada de cola ya que es ligeramente más fácil de hacer cuando la llamada de retorno está aquí ya que no hay necesidad de rastrear el resto del código para encontrar -recursivo o no (basta con buscar saltos al final del cuerpo del método). Pero no conozco el estado actual del compilador JIT con respecto a este caso específico, por lo que incluso puede no ser un problema. –

+0

¡Los pequeños detalles sucios! De eso estoy hablando .. Gracias nobugz :) – HashName

3

No estoy de acuerdo, creo que una sola y única de cada método hace que el código sea mucho más fácil de leer y depurar. Las declaraciones de retorno múltiples en una función pueden hacer que el código de navegación sea más comlpex. De hecho (si es posible para refactorizar) es mejor tener funciones más pequeñas que decir funciones más grandes con múltiples salidas.

Cuestiones relacionadas