在 Julia 中将一些常量参数传递给函数的最有效方法是什么?

What is the most efficient way to pass some constant arguments to a function in Julia?

假设我有以下功能

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 ] 使用和不使用 memoize 的输出:

没有:

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

也许缓存您对 do_some_intense_stuff(a) 的调用结果会有所帮助,例如使用 Memoize.jl.