Предположим, у меня есть следующая функция
function foo(x::Float64, a::Float64)
if do_some_intense_stuff(a)
return bar(x)
else
return baz(x)
end
end
Предположим, что во время выполнения a
будет константой. Но x
не будет. Мне приходится запускать foo()
много раз, поэтому я хотел бы, чтобы он запускался как можно быстрее, что означает запуск do_some_intense_stuff
как можно реже. Поскольку a
является константой, во время выполнения мы знаем, какую ветвь должен занять оператор if
.
В идеале, я бы сделал следующее:
foowrapper(x) = foo(x,a)
Y = [foowrapper(x) for x in lots_of_x]
, и он быть намного быстрее, чем
Y = [foo(x,a) for x in lots_of_x]
Но этого не происходит. Я не виню компилятор в том, что он не оптимизировал мой код, поскольку я явно не сказал ему, что foo()
будет вызываться только с постоянным значением a
. Но есть ли у меня хороший способ сделать это?
Конечно, я всегда могу избавиться от foo
и просто написать этот оператор if
в глобальной области видимости, но это кажется неэлегантным, потому что все остальное программы не заботится о выходе do_some_intense_stuff()
Обновление:
Чтобы протестировать решение, предложенное ниже, я реализовал следующие функции. Я также изменил объявление foo()
, чтобы сделать a
целым числом по очевидным причинам:
function bar(x::Float64)
return 2 * x
#println("Ran bar for value ",x)
end
function baz(x::Float64)
return -2 * x
#println("Ran baz for value ",x)
end
@memoize function do_some_intense_stuff(a::Int64)
return isprime(a + 32614262352646106013967035018546810367130464316134634614)
end
И определил lots_of_x = 1.0:1.0:1000.0
.
Вот результат @benchmark Y = [foo(x,a) for x in lots_of_x ]
с мемоизацией и без:
Без:
BenchmarkTools.Trial:
memory estimate: 109.50 KiB
allocs estimate: 5001
--------------
minimum time: 6.858 ms (0.00% GC)
median time: 6.924 ms (0.00% GC)
mean time: 7.067 ms (0.77% GC)
maximum time: 78.747 ms (49.00% GC)
--------------
samples: 707
evals/sample: 1
С:
BenchmarkTools.Trial:
memory estimate: 39.19 KiB
allocs estimate: 2001
--------------
minimum time: 97.500 μs (0.00% GC)
median time: 98.801 μs (0.00% GC)
mean time: 108.897 μs (1.37% GC)
maximum time: 2.099 ms (93.76% GC)
--------------
samples: 10000