我想知道在let-block中分配临时数组是一个好主意,它包含了一些函数吗?一些玩具示例:而不是
function foo(x)
y = zeros(100)
for i in 1 : 100
y[i] = 2*x[i] - 1
end
do_something(y)
end
我会写一些类似的东西:
let
const y = zeros(100) # otherwise foo will be type-unstable due to 'global' y
function foo(x)
for i in 1 : 100
y[i] = 2*x[i] - 1
end
do_something(y)
end
end
可以通过@benchmark宏轻松检查,在第二种情况下,y-array的内存只分配一次,这显着提高了性能(在我的非玩具案例中)。我想知道这样做是一种“朱利安式”吗?
我会给你Julia 1.0的答案。对于Julia的早期版本,情况会有所不同。
要点1.使用let
的代码不会在Julia 1.0下运行,因为let
会创建本地范围,在本地范围内,您不能使用const
。
要点2.在全球范围内做这样的事情是完全可以的:
const y = zeros(100) # otherwise foo will be type-unstable due to 'global' y
function foo(x)
for i in 1 : 100
y[i] = 2*x[i] - 1
end
do_something(y)
end
而且你会有很好的表现,因为朱莉娅1.0知道y
有恒定类型并会优化它。结果是你将在全局范围内使用y
并在方法表中使用foo
(即你可以使用其名称调用foo
)。
第3点。你也可以像这样使用let
块:
const foo = let y = zeros(100)
function inner_foo(x)
for i in 1 : 100
y[i] = 2*x[i] - 1
end
do_something(y)
end
end
这次y
仅在本地范围内定义,不会泄漏到全局范围。 inner_foo
也没有在全局范围内定义,因此你必须将let块的返回值赋给变量foo
然后可以用来进行调用(如果稍后在某些函数中使用它,我将它设为const
以提高性能)
要点4.但是请注意,这个几乎相同的代码不会那么好,因为Julia 1.0存在变量y
类型推断的问题(希望将来会修复)
const foo = let
y = zeros(100)
function inner_foo(x)
for i in 1 : 100
y[i] = 2*x[i] - 1
end
do_something(y)
end
end
总结:如果你使用let
块的决定主要取决于你在global
范围内必须看到的内容(因为在let
中定义的内容在全局范围内不可见),如果你使用let
块,最好定义你想要的变量用作let
块定义的一部分。