将程序从 Python 翻译成 Julia 后,我非常不满意:
- 对于小/非常小的输入,Python 更快
- 对于中等输入,Julia 更快(但没那么快)
- 对于大输入,Python 更快
我认为原因是我不明白内存分配是如何工作的(这里自学者,没有CS背景)。我会在这里发布我的代码,但它太长且太具体,除了我之外,它对任何人都没有好处。因此我做了一些实验,现在我有一些问题。
考虑这个简单的script.jl
:
function main()
@time begin
a = [1,2,3]
end
end
main()
当我运行它时,我得到:
$ julia script.jl
0.000004 seconds (1 allocation: 96 bytes)
1.为什么是 96 字节?当我设置a = []
我得到 64 个字节(为什么空数组的重量如此之大?)。 96 字节 - 64 字节 = 32 字节。但a
is an Array{Int64,1}
。 3 * 64 位 = 3 * 8 字节 = 24 字节!= 32 字节。
2.为什么我设置了还是得到96字节a = [1,2,3,4]
?
3.为什么我运行此命令时会得到 937.500 KB:
function main()
@time begin
for _ in 1:10000
a = [1,2,3]
end
end
end
main()
而不是 960.000 KB?
4.为什么,例如,filter()
这么低效?看看这个:
check(n::Int64) = n % 2 == 0
function main()
@time begin
for _ in 1:1000
a = [1,2,3]
b = []
for x in a
check(x) && push!(b,x)
end
a = b
end
end
end
main()
$ julia script.jl
0.000177 seconds (3.00 k allocations: 203.125 KB)
instead:
check(n::Int64) = n % 2 == 0
function main()
@time begin
for _ in 1:1000
a = [1,2,3]
a = filter(check,a)
end
end
end
main()
$ julia script.jl
0.002029 seconds (3.43 k allocations: 225.339 KB)
如果我使用匿名函数(x -> x % 2 == 0
)我得到的不是检查内部过滤器,而是:
$ julia script.jl
0.004057 seconds (3.05 k allocations: 206.555 KB)
如果内置函数速度较慢并且需要更多内存,为什么我应该使用它?