Каким образом я могу сравнить функцию Джулии?

11

Фон

Я самообучался машинному обучению и недавно начал изучать экосистему машинного обучения Джулии.


Исходя из опыта работы с питоном и имея некоторый опыт работы с Tensorflow и OpenCV / skimage, я хочу сравнить библиотеки Julia ML (Flux / JuliaImages) со своими аналогами, чтобы увидеть, насколько быстро или медленно он действительно выполняет CV (любые) задачи, и решить, Я должен перейти к использованию Джулии.

Я знаю, как получить время, необходимое для выполнения функции в Python, используя timeitтакой модуль:

#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

Как сравнить время выполнения функции, выполняющей ту же задачу в Юлии, используя соответствующую библиотеку (в данном случае, JuliaImages).

Предоставляет ли Юлия какую-либо функцию / макрос для времени / теста?

PseudoCodeNerd
источник

Ответы:

10

using BenchmarkToolsрекомендуемый способ сравнения функций Julia. Если вы не синхронизируете что-то, что занимает много времени, используйте один @benchmarkили менее подробные @btimeмакросы, экспортированные из него. Поскольку механизм, стоящий за этими макросами, оценивает целевую функцию много раз, @timeон полезен для сравнительного анализа медленных процессов (например, когда требуется доступ к диску или очень трудоемкие вычисления).

Это важно использовать @btimeили @benchmarkправильно, это позволяет избежать вводящих в заблуждение результатов. Обычно вы тестируете функцию, которая принимает один или несколько аргументов. При бенчмаркинге все аргументы должны быть внешними переменными: (без макроса бенчмарка)

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

Функция будет оценена много раз. Чтобы предотвратить повторную оценку аргументов функции всякий раз, когда функция оценивается, мы должны пометить каждый аргумент, добавив префикс a $к имени каждой переменной, которая используется в качестве аргумента. Макросы сравнительного анализа используют это, чтобы указать, что переменная должна быть оценена (разрешена) один раз, в начале процесса сравнительного анализа, а затем результат должен быть повторно использован непосредственно, как:

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

Хотя есть параметры, которые можно отрегулировать, значения по умолчанию обычно работают хорошо. Для получения дополнительной информации о BenchmarkTools для опытных ursers смотрите руководство .

Джеффри Сарнофф
источник
7

Джулия предоставляет два макроса для определения времени выполнения кода. Эти :

  • @время
  • @benchmark : внешний, установитьPkg.add("BenchmarkTools")

Использование @benchmark от BenchmarkTools очень просто и будет полезно для сравнения скорости двух языков. Пример использования @bencharkпротив предоставленной вами скамьи Python.

using Images, FileIO, BenchmarkTools

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

Вывод :

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

Теперь, чтобы сравнить среднее время, вы должны samplesуказать (46) как число в вашем коде Python Timeit и разделить его на то же число, чтобы получить среднее время выполнения.

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

Вы можете следить за этим процессом для сравнения любой функции в Julia и Python. Я надеюсь, что ваши сомнения были очищены.


Примечание : со статистической точки зрения @benchmark намного лучше, чем @time.

PseudoCodeNerd
источник
2
Обратите внимание, что временные помехи в основном положительные, что означает, что минимальное время часто (не всегда) более информативно. @btimeи @belapsedвернуть только минимальное время.
Фредрик Багге