2012-04-19 43 views
8

Estoy trabajando en una aplicación C# .NET que utiliza algunas fórmulas científicas bastante complejas en grandes conjuntos de datos (10 millones de puntos de datos en promedio). Parte de lo que estoy haciendo requiere optimizar las implementaciones de la fórmula de la mejor manera posible.¿La instrucción goto es lenta en C#?

Me di cuenta de que una implementación de fórmula usa goto, y eso me hizo preguntarme: ¿es ir más lento que otras construcciones de control de flujo?

+4

Por favor hazte un favor y no uses goto en C# !!! – MUG4N

+3

@ MUG4N No hay nada de malo con los goto, es cómo los usas que los hacen malvados – GETah

+0

@GETah Y son muy raramente usados ​​de manera responsable, y hay muy poco valor en usarlos sobre las alternativas, entonces, ¿por qué tomar los riesgos? – Servy

Respuesta

11

es más lento que otras construcciones de control de flujo?

No. Todas las otras construcciones de control de flujo son básicamente goto de todos modos.

+0

Gracias. No estoy seguro de por qué alguien marcó mi pregunta. – kevin628

+3

Es una pregunta perfectamente razonable. La gente simplemente reacciona visceralmente cuando ven algo que ver con 'goto'. – jason

4

La instrucción goto en C# no es más lenta que cualquier otra construcción de flujo de control. De hecho, la gran mayoría de las construcciones de flujo de control (if, while, for, etc ...) se implementa en términos de goto.

Por ejemplo:

if (someExpr) { 
    Console.WriteLine("here"); 
} 
Console.WriteLine("there"); 

se compila esencialmente a la siguiente

gotoIf !someExpr theLabel; 
Console.WriteLine("here"); 
theLabel: 
Console.WriteLine("there"); 
1

if s y for se traducen a goto s internamente por el compilador para que no sean lo más rápido que goto s

4

Me di cuenta esa implementación de una fórmula usa goto, y eso me hizo pensar : ¿es más lenta que otras construcciones de control de flujo?

goto no será más lento que cualquier otro mecanismo de control de flujo. Es, como la mayoría de los mecanismos de control de flujo compilados en una instrucción br.s (o similar) MSIL. Sin embargo, hay algunas situaciones donde goto puede ser un poco más rápido. En su mayoría se limitan a situaciones que implican el uso de break y continue dentro de bucles anidados. Considera el siguiente código.

bool condition = false; 
for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      condition = Evaluate(i, j, k); 
      if (condition) 
      { 
       // break out of everything 
      } 
     } 
    } 
} 

Existen diferentes formas en que se puede salir de todo. Aquí hay un método.

bool condition = false; 
for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      condition = Evaluate(i, j, k); 
      if (condition) break; 
     } 
     if (condition) break; 
    } 
    if (condition) break; 
} 

El problema es que cada bucle debe comprobar la bandera condition. Podríamos refactorizar esto con un goto para hacerlo un poco más eficiente y un poco más elegante para arrancar.

for (int i = 0; i < BigNumber; i++) 
{ 
    for (int j = 0; j < i; j++) 
    { 
     for (int k = 0; k < j; k++) 
     { 
      if (Evaluate(i, j, k)) goto BAILOUT; 
     } 
    } 
} 
BAILOUT: 
+2

+1 para el excelente ejemplo de cuando goto es la solución más limpia y fácil de mantener. Otro ejemplo es el código con muchas condiciones de error potencial que todos utilizan goto para rescatar a una salida de error común. –