De que maneira posso comparar uma função Julia?

11

fundo

Eu aprendi sozinho o aprendizado de máquinas e recentemente comecei a me aprofundar no ecossistema Julia Machine Learning.


Vindo de um background em python e tendo alguma experiência com Tensorflow e OpenCV / skimage, quero comparar as bibliotecas Julia ML (Flux / JuliaImages) com suas contrapartes para ver o quão rápido ou lento ele realmente executa as tarefas de CV (qualquer) e decidir se Eu deveria passar a usar Julia.

Eu sei como obter o tempo necessário para executar uma função em python usando o 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

Como se compara o tempo de execução de uma função que executa a mesma tarefa em Julia usando a biblioteca apropriada (neste caso, JuliaImages).

Julia fornece alguma função / macro para tempo / referência?

PseudoCodeNerd
fonte

Respostas:

10

using BenchmarkToolsé a maneira recomendada de comparar as funções de Julia. A menos que você esteja cronometrando algo que leva bastante tempo, use uma @benchmarkou mais @btimemacros menos detalhadas exportadas a partir dele. Como o mecanismo por trás dessas macros avalia a função de destino várias vezes, @timeé útil para comparar coisas que ocorrem lentamente (por exemplo, onde o acesso ao disco ou cálculos demorados estão envolvidos).

É importante usar @btimeou @benchmarkcorretamente, isso evita resultados enganosos. Normalmente, você está comparando uma função que recebe um ou mais argumentos. Ao fazer benchmarking, todos os argumentos devem ser variáveis ​​externas: (sem a macro de benchmark)

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

A função será avaliada várias vezes. Para impedir que os argumentos da função sejam reavaliados sempre que a função for avaliada, devemos marcar cada argumento prefixando $a ao nome de cada variável usada como argumento. As macros de benchmarking usam isso para indicar que a variável deve ser avaliada (resolvida) uma vez, no início do processo de benchmarking e, em seguida, o resultado deve ser reutilizado diretamente como é:

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

Embora existam parâmetros que podem ser ajustados, os valores padrão geralmente funcionam bem. Para informações adicionais sobre o BenchmarkTools para ursers experientes, consulte o manual .

Jeffrey Sarnoff
fonte
7

Julia fornece duas macros para cronometrar / comparar o tempo de execução do código. Esses são :

  • @Tempo
  • @benchmark : externo, instale porPkg.add("BenchmarkTools")

Usar o @benchmark do BenchmarkTools é muito fácil e ajudaria você a comparar a velocidade dos dois idiomas. Exemplo de uso @bencharkno banco python que você forneceu.

using Images, FileIO, BenchmarkTools

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

Resultado :

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

Agora, para comparar o tempo médio, você deve colocar samples(46) o número no seu código de tempo python e dividi-lo pelo mesmo número para obter o tempo médio de execução.

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

Você pode seguir este processo para comparar qualquer função no Julia e no Python. Espero que você tenha duvidado.


Nota : Do ponto de vista estatístico, o @benchmark é muito melhor que o @time.

PseudoCodeNerd
fonte
2
Observe que o ruído do tempo é principalmente positivo, o que implica que o tempo mínimo é geralmente (nem sempre) mais informativo. @btimee @belapsedretorne apenas o tempo mínimo.
Fredrik Bagge