使用Iterator.jl中的product
可以迭代输入的笛卡尔积中的所有组合。然而,它变得比仅仅强迫它慢得多......":
using Iterators
@time(
for tup in product(-100:100, -100:100, -100:100)
# do something with silly tup
maximum(tup)
end
)
# 10.033157 seconds (64.97 M allocations: 3.510 GB, 3.03% gc time)
直接嵌套循环:
@time(
for x in -100:100, y in -100:100, z in -100:100
# do something silly with x, y, z
maximum([x y z])
end
)
# 0.420949 seconds (8.12 M allocations: 867.374 MB, 4.31% gc time)
有谁知道为什么? (使用从product
返回的迭代器将导致块中的代码更简单,允许在大型笛卡尔网格上使用前pmap
。使用Julia v"0.5.1"
)
答案 0 :(得分:3)
Iterators.jl中的许多功能现在都内置于版本0.6中的Julia< Base.Iterators
模块中。您可以使用using Iterators
中的版本代替Base.Iterators
而不是
julia> @time(
for tup in product(-100:100, -100:100, -100:100)
# do something with silly tup
maximum(tup)
end
)
18.110503 seconds (64.98 M allocations: 3.510 GiB, 3.32% gc time)
julia> @time(
for tup in Base.Iterators.product(-100:100, -100:100, -100:100)
# do something with silly tup
maximum(tup)
end
)
0.658809 seconds (8.12 M allocations: 247.821 MiB, 5.50% gc time)
它并未对此结果产生重大影响,但总的来说,您不应该在全球范围内进行基准测试,因为它不能代表您在Julia中运行典型程序的方式。将代码包装在函数中,而不是。
如果您对两者的不同之处感到好奇,可以查看the difference in implementations。 Base的实现经过高度优化,因为它在许多核心结构(如理解和生成器)中使用。 Iterators.jl实现速度缓慢的原因有很多,包括那些copy
调用,使用非专用Any[]
向量以及state[2]
中的类型不稳定。
答案 1 :(得分:1)
你的时间输出告诉你多少:
通过3.5GB内存咀嚼product()
的64.97M分配;而只有8.12M的分配只吃' 867MB。
内存分配很慢。如果你有更多的分配和一个数量级更大的分配担心,那将会减慢你的速度。