¿De qué manera puedo comparar una función de Julia?

11

Antecedentes

Aprendí por mí mismo el aprendizaje automático y recientemente comencé a profundizar en el ecosistema Julia Machine Learning.


Viniendo de un fondo de Python y teniendo algo de Tensorflow y OpenCV / skimageexperiencia, quiero comparar las bibliotecas de Julia ML (Flux / JuliaImages) con sus contrapartes para ver qué tan rápido o lento realmente realiza las tareas de CV (cualquier) y decidir si Debería cambiar a usar Julia.

Sé cómo obtener el tiempo necesario para ejecutar una función en Python usando un timeitmódulo como este:

#Loading an Image using OpenCV

s = """\
img = cv2.imread('sample_image.png', 1)
"""
setup = """\
import timeit
"""
print(str(round((timeit.timeit(stmt = s, setup = setup, number = 1))*1000, 2)) + " ms")
#printing the time taken in ms rounded to 2 digits

¿Cómo se compara el tiempo de ejecución de una función que realiza la misma tarea en Julia usando la biblioteca apropiada (en este caso JuliaImages)?

¿Julia proporciona alguna función / macro a tiempo / punto de referencia?

PseudoCodeNerd
fuente

Respuestas:

10

using BenchmarkToolses la forma recomendada de comparar las funciones de Julia A menos que esté cronometrando algo que lleve bastante tiempo, use una @benchmarko las @btimemacros menos detalladas exportadas desde allí. Debido a que la maquinaria detrás de estas macros evalúa la función de destino muchas veces, @timees útil para realizar una evaluación comparativa de cosas que se ejecutan lentamente (por ejemplo, cuando se trata de acceso al disco o cálculos que requieren mucho tiempo).

Es importante usarlo @btimeo @benchmarkcorrectamente, esto evita resultados engañosos. Por lo general, está comparando una función que toma uno o más argumentos. Al realizar evaluaciones comparativas, todos los argumentos deben ser variables externas: (sin la macro de referencia)

x = 1
f(x)
# do not use f(1)

La función se evaluará muchas veces. Para evitar que los argumentos de la función se vuelvan a evaluar cada vez que se evalúa la función, debemos marcar cada argumento con el prefijo $a al nombre de cada variable que se usa como argumento. Las macros de evaluación comparativa usan esto para indicar que la variable debe evaluarse (resolverse) una vez, al comienzo del proceso de evaluación comparativa y luego el resultado se debe reutilizar directamente como es:

julia> using BenchmarkTools
julia> a = 1/2;
julia> b = 1/4;
julia> c = 1/8;
julia> a, b, c
(0.5, 0.25, 0.125)

julia> function sum_cosines(x, y, z)
         return cos(x) + cos(y) + cos(z)
       end;

julia> @btime sum_cosines($a, $b, $c);  # the `;` suppresses printing the returned value
  11.899 ns (0 allocations: 0 bytes)    # calling the function takes ~12 ns (nanoseconds)
                                        # the function does not allocate any memory
# if we omit the '$', what we see is misleading
julia> @btime sum_cosines(a, b, c);    # the function appears more than twice slower 
 28.441 ns (1 allocation: 16 bytes)    # the function appears to be allocating memory
# @benchmark can be used the same way that @btime is used
julia> @benchmark sum_cosines($a,$b,$c) # do not use a ';' here
BenchmarkTools.Trial:
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     12.111 ns (0.00% GC)
  median time:      12.213 ns (0.00% GC)
  mean time:        12.500 ns (0.00% GC)
  maximum time:     39.741 ns (0.00% GC)
  --------------
  samples:          1500
  evals/sample:     999

Si bien hay parámetros que se pueden ajustar, los valores predeterminados generalmente funcionan bien. Para obtener información adicional sobre BenchmarkTools para ursers experimentados, consulte el manual .

Jeffrey Sarnoff
fuente
7

Julia proporciona dos macros para el tiempo de ejecución del código de referencia / evaluación comparativa. Estos son :

  • @hora
  • @benchmark : externo, instalar porPkg.add("BenchmarkTools")

Usar BenchmarkTools '@benchmark es muy fácil y sería útil para comparar la velocidad de los dos idiomas. Ejemplo de uso @bencharkcontra el banco de python que proporcionó.

using Images, FileIO, BenchmarkTools

@benchmark img = load("sample_image.png")

Salida:

BenchmarkTools.Trial: 
  memory estimate:  3.39 MiB
  allocs estimate:  322
  --------------
  minimum time:     76.631 ms (0.00% GC)
  median time:      105.579 ms (0.00% GC)
  mean time:        110.319 ms (0.41% GC)
  maximum time:     209.470 ms (0.00% GC)
  --------------
  samples:          46
  evals/sample:     1

Ahora, para comparar el tiempo medio, debe poner samples(46) como el número en su código de tiempo de python y dividirlo por el mismo número para obtener el tiempo medio de ejecución.

print(str(round((timeit.timeit(stmt = s, setup = setup, number = 46)/46)*1000, 2)) + " ms")

Puede seguir este proceso para comparar cualquier función tanto en Julia como en Python. Espero que tu duda haya sido aclarada.


Nota : Desde un punto de vista estadístico, @benchmark es mucho mejor que @time.

PseudoCodeNerd
fuente
2
Tenga en cuenta que el ruido de temporización es mayormente positivo, lo que implica que el tiempo mínimo es a menudo (no siempre) más informativo. @btimey @belapsedsolo devuelve el tiempo mínimo.
Fredrik Bagge