Всегда ли макрос быстрее, чем функция в Юлии? - PullRequest
0 голосов
/ 27 сентября 2018

Мне интересно передать значение легкой функции (2 в минимальном примере ниже).Мой минимальный пример показывает, что макрос намного быстрее, чем функция.Это правильно или я сделал ошибку?

using BenchmarkTools
macro func!(arg)
    arg = eval(arg)
    for i in 1:length(arg)
        arg[i] = 2
    end
    return nothing
end
function func!(arg)
    for i in 1:length(arg)
        arg[i] = 2
    end
    return nothing
end
x = ones(10^3)
@btime @func!(x) --> 0.001 ns (0 allocations: 0 bytes)
@btime func!(x) --> 332.272 ns (0 allocations: 0 bytes)

EDIT1:

Нет, это не быстрее.Кажется, что макросы @btime и @time не работают с макросами.Я проверил это с помощью макроса @time в минимальном примере ниже.И я посчитал секунды для макроса, даже если @time сказал мне, что он почти не использует время.

x = ones(10^7)
@time @func!(x) --> 0.000001 seconds (3 allocations: 144 bytes)
@time func!(x) --> 0.007362 seconds (4 allocations: 160 bytes)

1 Ответ

0 голосов
/ 28 сентября 2018

Опять же, как и в прошлый раз, есть два комментария.

На самом деле макрос работает медленнее

Рассмотрим этот код, который оценивает фактическое время, необходимое макросу и функции для завершения своей работы:

julia> x = ones(10^8);

julia> t1 = time_ns()
0x00006937ba4da19e

julia> @func!(x)

julia> t2 = time_ns()
0x00006939ebcb5c41

julia> Int(t2 - t1)
9420257955

julia>

julia> x = ones(10^8);

julia> t1 = time_ns()
0x0000693a0ee9452f

julia> func!(x)

julia> t2 = time_ns()
0x0000693a16ea941e

julia> Int(t2 - t1)
134303471

И вы видите, что функция значительно быстрее.Разница в том, что время расходуется в разные моменты (время компиляции и время выполнения, а @btime измеряет время выполнения).

Макрос работает, только если его аргумент определен в глобальной области видимости

Например, следующий код завершается ошибкой:

julia> function test()
           abc = [1,2,3]
           @func!(abc)
           abc
       end
ERROR: LoadError: UndefVarError: abc not defined

while:

julia> function test()
           abc = [1,2,3]
           func!(abc)
           abc
       end
test (generic function with 1 method)

julia> test()
3-element Array{Int64,1}:
 2
 2
 2

, поэтому функция и макрос на самом деле делают разные вещи.

В общем, я обычно рекомендую не делатьиспользуйте макросы, если для этого нет веских причин.

...