Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

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

He codificado una estructura de datos para la asignación a la universidad, y 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 convertir una llamada O (n) en O (1) en algunos.

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

¿Fue útil?

Solución

Puede usar la clase de cronómetro incorporada para " Proporciona un conjunto de métodos y propiedades que puede usar para medir con precisión el tiempo transcurrido. " Si está buscando una forma manual de hacerlo. Aunque no estoy seguro en automatizado.

Otros consejos

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 punto 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.

Robé la mayoría 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);
}

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

  1. Descarte el primer lote de (miles) iteraciones. Lo más probable es que se vean afectados por el JITter.
  2. Ejecutar el punto de referencia en un objeto Thread separado puede proporcionar resultados mejores y más estables. No sé por qué.
  3. He visto a algunas personas usando Thread.Sleep por cualquier razón antes de ejecutar el punto de referencia. Esto solo empeorará las cosas. No se porque. 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 lentamente.
  5. Compile su 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 compilar sin optimización afectará la confiabilidad de su punto de referencia.
  6. Al compilar con optimizaciones habilitadas, a veces es necesario evaluar de alguna manera el resultado del punto de referencia (por ejemplo, imprimir un valor, etc.). De lo contrario, el compilador puede "descubrir" que algunos cálculos son inútiles y simplemente no los realizarán.
  7. La invocación de delegados 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 punto 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 no son buenos para comparar realmente dos cosas diferentes de manera confiable.
  9. En general, las soluciones sofisticadas de evaluación comparativa pueden tener una sobrecarga notable. Por ejemplo, si desea comparar muchos objetos usando una interfaz, puede ser tentador ajustar cada objeto en una clase. Sin embargo, recuerde que el constructor de la clase también tiene gastos generales que deben tenerse en cuenta. Es mejor mantener todo lo más simple y directo posible.

Parece que quiere un profiler . Recomiendo encarecidamente el EQATEC profiler , siendo el mejor gratuito que he probado. Lo bueno de este método sobre un cronómetro simple 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 el 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top