julia - 为什么用户定义的类型与 Julia 中的内置语言类型一样快速和紧凑?
问题描述
我已经查看了很多文档,但我找不到具体的答案。
Julia标准原始类型都是在语言本身中定义的,Julia 允许您声明自己的原始类型,但我不知道这是否是程序员定义的类型与内置类型一样快速和紧凑的原因。我什至检查了 GitHub 上的源代码,更具体地说是bool.jl ,它是定义 int 的数值类型的地方,但我不敢猜测。有人可以给我一个具体的答案吗?谢谢。
解决方案
这是一个难以准确回答并涵盖所有极端情况的问题。
这是我对一个简单(希望不要过于简化)的解释:
- Julia 代码被编译为接下来执行的本机汇编指令。
- 如果 Julia 编译器能够证明两个实现是等价的,那么您可以预期将为它们生成相同的本机汇编指令(这不是 100% 正确,但根据我的经验,这是一个很好的近似值)。
- 这意味着在本机汇编级别,您使用什么类型(内置或您自己的)并不重要,只要您要执行的操作和编译器具有的类型信息相同。
这是一个简短的示例(我使用的是 a struct
,但这与您自己的原始类型的情况相同):
struct A
a::Int
end
function f(x::Int, n)
s = Int[]
for i in 1:n
push!(s,x)
end
s
end
function f(x::A, n)
s = Int[]
for i in 1:n
push!(s,x.a)
end
s
end
function f2(x::A, n)
s = A[]
for i in 1:n
push!(s,x)
end
s
end
现在,如果您运行@code_native f(1, 10^6)
, @code_native f(A(1), 10^6)
,@code_native f2(A(1), 10^6)
您将看到生成的代码(几乎)是相同的。
您可以在基准测试中看到它的效果:
julia> using BenchmarkTools
julia> @btime f(1, 10^6);
8.567 ms (20 allocations: 9.00 MiB)
julia> @btime f(A(1), 10^6);
8.528 ms (20 allocations: 9.00 MiB)
julia> @btime f2(A(1), 10^6);
8.446 ms (20 allocations: 9.00 MiB)
您有相同的时间和相同数量的分配。
但现在考虑以下定义:
struct C
a
end
function f(x::C, n)
s = Int[]
for i in 1:n
push!(s,x.a)
end
s
end
现在对这个函数进行基准测试给出:
julia> @btime f(C(1), 10^6);
19.855 ms (21 allocations: 9.00 MiB)
原因 in type C
fielda
可以保存任何值,因此编译器无法证明这x.a
是一个Int
并且因此必须做一些额外的工作。您可以通过检查@code_warntype f(C(1), 10^6)
.@code_warntype f(A(1), 10^6)
推荐阅读
- ruby-on-rails - 如何将 Rails 的静态页面打包成 ruby gem?
- typescript - 如何在打字稿中迭代字符串和数字混合枚举?
- apache-flink - 如何将自定义表源和自定义表接收器与 SQL 客户端集成?
- laravel - Laravel Vue Js npm run dev url
- php - Webmin cron 作业命令
- javascript - 反应路由器dom不路由
- opengl-es - 使用触发器来衡量移动 GPU 性能是否足够?
- javascript - Chrome 扩展弹出窗口不使用 chrome.storage.sync 保留数据集
- javascript - VueJS:在可重用组件中使用多个组件
- json - 解析 json 时出现“NameError: name api_key is not defined”