Método de evaluación comparativa de llamadas en C #

Estoy buscando una manera de comparar las llamadas de método en C #.

He codificado una estructura de datos para la asignación de la universidad, y solo se me ocurrió una forma de optimizar un poco, pero de una manera que agregaría un poco de sobrecarga en todas las situaciones, al mismo tiempo que convertía una llamada O (n) en O (1) en algunos.

Ahora quiero ejecutar ambas versiones con los datos de prueba para ver si vale la pena implementar la optimización. Sé que en Ruby, podría ajustar el código en un bloque de Benchmark y hacer que produzca el tiempo necesario para ejecutar el bloque en la consola. ¿Hay algo así como disponible para C #?

Podría usar la clase Cronómetro incorporada para “Proporciona un conjunto de métodos y propiedades que puede usar para medir con precisión el tiempo transcurrido”. Si buscas una forma manual de hacerlo. Aunque no estoy seguro de automatizado.

Robado (y modificado) de la respuesta de Yuriy:

private static void Benchmark(Action act, int iterations) { GC.Collect(); act.Invoke(); // run once outside of loop to avoid initialization costs Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { act.Invoke(); } sw.Stop(); Console.WriteLine((sw.ElapsedMilliseconds / iterations).ToString()); } 

A menudo, un método particular tiene que inicializar algunas cosas, y no siempre desea incluir esos costos de inicialización en su índice de referencia general. Además, desea dividir el tiempo total de ejecución por el número de iteraciones, de modo que su estimación sea más o menos independiente del número de iteraciones.

Aquí hay algunas cosas que he encontrado por prueba y errores.

  1. Deseche el primer lote de (miles) iteraciones. Lo más probable es que sean afectados por el JITter.
  2. La ejecución del punto de referencia en un objeto Thread separado puede dar resultados mejores y más estables. No se por que
  3. He visto a algunas personas usar Thread.Sleep por cualquier motivo antes de ejecutar el punto de referencia. Esto solo empeorará las cosas. No se por que Posiblemente debido al JITter.
  4. Nunca ejecute el punto de referencia con la depuración habilitada. El código probablemente ejecutará órdenes de magnitud más lentas.
  5. Comstack tu aplicación con todas las optimizaciones habilitadas. Algunos códigos pueden verse afectados drásticamente por la optimización, mientras que otros no lo serán, por lo que la comstackción sin optimización afectará la confiabilidad de su punto de referencia.
  6. Al comstackr con las optimizaciones habilitadas, a veces es necesario evaluar de alguna manera la salida del índice de referencia (por ejemplo, imprimir un valor, etc.). De lo contrario, el comstackdor puede “descifrar” que algunos cálculos son inútiles y simplemente no los realizará.
  7. La invocación de delegates puede tener una sobrecarga notable al realizar ciertos puntos de referencia. Es mejor poner más de una iteración dentro del delegado, de modo que la sobrecarga tenga poco efecto en el resultado del índice de referencia.
  8. Los perfiladores pueden tener sus propios gastos generales. Son buenos para decirle qué partes de su código son cuellos de botella, pero en realidad no son buenos puntos de referencia para evaluar dos cosas diferentes de manera confiable.
  9. En general, las soluciones de evaluación comparativa de lujo pueden tener una sobrecarga notable. Por ejemplo, si desea comparar muchos objetos utilizando una interfaz, puede ser tentador envolver cada objeto en una clase. Sin embargo, recuerde que el constructor de la clase también tiene una sobrecarga que debe tenerse en cuenta. Es mejor mantener todo lo más simple y directo posible.

Robé la mayor parte de lo siguiente del método de Jon Skeet para la evaluación comparativa:

 private static void Benchmark(Action act, int interval) { GC.Collect(); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < interval; i++) { act.Invoke(); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } 

Parece que quieres un perfilador . Recomiendo encarecidamente el perfilador EQATEC , ya que es el mejor que he probado. Lo bueno de este método sobre un simple cronómetro es que también proporciona un desglose del rendimiento sobre ciertos métodos / bloques.

Los perfiladores ofrecen los mejores puntos de referencia ya que diagnostican todo su código, sin embargo, lo ralentizan mucho. Los perfiladores se utilizan para encontrar cuellos de botella.

Para optimizar un algoritmo, cuando sepa dónde están los cuellos de botella, use un diccionario de nombre -> cronómetro, para realizar un seguimiento de las secciones críticas de rendimiento durante el tiempo de ejecución.