function - 将一些常量参数传递给 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。
推荐阅读
- android-tv - 为 BrowseSupportFragment 膨胀新布局
- javascript - 如何在 Google Chrome 扩展程序中将多行内联脚本注入 HTML DOM 模板?
- haskell - Haskell RTS 选项中没有 -Nx 标志
- ssh - 无法通过 Github Action 工作流程中的 SSH 连接
- kotlin - RecyclerView + Fragment TabLayout
- api - 我需要有关如何将 Slate 用于 API 文档的帮助
- python - 如何计算 PDF 和 CDF numpy 统一 RV
- swift - UINavigationBar 使用灵活的空间来均匀分布栏按钮项
- python - 提交烧瓶表单时收到 400 错误请求错误
- azure - 从 Azure Web 应用程序的 asp.net 核心中的 docker compose 文件中获取环境变量