gpt4 book ai didi

julia - 在 Julia 中使用变量后 for 循环明显变慢

转载 作者:行者123 更新时间:2023-12-04 00:53:57 25 4
gpt4 key购买 nike

我对以下代码的性能感到非常困惑,在将“2”替换为变量“z=2”后,for 循环运行得更慢:

julia> @elapsed for a=1:2:24996
for b=1:2:24996
end
end
2.0e-7

julia> z=2
2

julia> @elapsed for a=1:z:24996
for b=1:z:24996
end
end
14.455516599

关于原因以及如何防止此类延迟的任何想法?谢谢!

最佳答案

这是因为 z 是在全局范围内定义的,不是常量,这意味着它可以随时更改值。更重要的是,它还可以改变类型。这可以防止 Julia 编译器进行大量优化。

TLDR:始终尝试避免在全局范围内使用非常量变量进行性能关键型操作!

但是,如果您将您的值定义为常量(下面的 w 示例)或者您的变量是在本地范围内定义的(下面的 y 示例),那么循环被编译成与使用文字一样高效的代码:

julia> @elapsed for a=1:2:24996
for b=1:2:24996
end
end
1.16e-7
julia> z=2
2

julia> @elapsed for a=1:z:24996
for b=1:z:24996
end
end
10.726003104
julia> const w = 2
2

julia> @elapsed for a=1:w:24996
for b=1:w:24996
end
end
1.58e-7
julia> @elapsed let y=2
for a=1:y:24996
for b=1:y:24996
end
end
end
1.05e-7

另请注意,您的基准测试存在一些问题。

首先,您的基准测试不会计算任何内容。这是一个问题,因为一旦编译器可以自由进行任何优化,它就会优化所有内容。

您在此处测量的运行时间更多地与编译有关,而不是与问题的大小有关。例如,当问题规模增加时,请看下面会发生什么:

julia> @elapsed for a=1:2:2*24996
for b=1:2:2*24996
end
end
1.21e-7

julia> @elapsed for a=1:2:4*24996
for b=1:2:4*24996
end
end
1.31e-7

其次,建议对包装在函数中的代码执行此类微基准测试,并使用 BenchmarkTools 提供的宏(例如,BenchmarkTools.@belapsed 应该优先于 @elapsed),以便可以执行更准确的测量,并省略编译时间。

解决所有这些问题后,我们以一种更有说服力的方式看到,在函数中使用局部变量的代码与使用常量文字的代码一样快:


julia> function foo(n)
s = 0.
for a=1:2:n
for b=1:2:n
s += a+b
end
end
s
end
foo (generic function with 1 method)

julia> @btime foo(24996)
224.787 ms (0 allocations: 0 bytes)
3.904375299984e12

julia> function foo(n, z)
s = 0.
for a=1:z:n
for b=1:z:n
s += a+b
end
end
s
end
foo (generic function with 2 methods)

julia> @btime foo(24996, 2)
224.762 ms (0 allocations: 0 bytes)
3.904375299984e12

关于julia - 在 Julia 中使用变量后 for 循环明显变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64163032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com