最近,我对Julia-lang很感兴趣,因为它声称是一种动态语言,具有接近C的性能。但是,到目前为止,我的经验并不好(至少在性能方面(。 我正在编写的应用程序需要随机访问特定的数组索引,然后将它们的值与其他特定的数组索引进行比较(在多次迭代中(。以下代码模拟了我对程序的需求: 我的 Julia 代码在大约 8 秒内完成执行,而 java 脚本代码在 chrome 环境中需要不到 1 秒! 我用朱莉娅代码做错了什么吗?提前非常感谢。
朱莉娅代码在这里:
n=5000;
x=rand(n)
y=rand(n)
mn=ones(n)*1000;
tic();
for i in 1:n;
for j in 1:n;
c=abs(x[j]-y[i]);
if(c<mn[i])
mn[i]=c;
end
end
end
toc();
Javascript代码:(比上面的julia代码快>8倍!(
n=5000; x=[]; y=[]; mn=[];
for(var i=0; i<n; i++){x.push(Math.random(1))}
for(var i=0; i<n; i++){y.push(Math.random(1))}
for(var i=0; i<n; i++){mn.push(1000)}
console.time('test');
for(var i=0; i<n; i++){
for(var j=0; j<n; j++){
c=Math.abs(x[j]-y[i]);
if(c<mn[i]){
mn[i]=c;
}
}
}
console.timeEnd('test');
性能提示
避免全局变量
全局变量的值可能会发生变化,因此其类型也会发生变化 在任何时候。这使得编译器难以优化 使用全局变量的代码。变量应该是局部的,或者作为 函数的参数,只要有可能。
任何对性能至关重要或正在基准测试的代码都应该是 在函数内。
我们发现全局名称通常是常量,并声明它们 因此大大提高了性能:
julia> const n = 5000; const x, y = rand(n), rand(n); const mn = fill(1000.0, n);
julia> function foo!(mn, x, y)
n = length(mn)
@inbounds for i in 1:n, j in 1:n
c = abs(x[j] - y[i])
if(c < mn[i])
mn[i] = c
end
end
return mn
end
foo! (generic function with 1 method)
julia> using BenchmarkTools: @btime
julia> @btime foo!(mn, x, y)
15.432 ms (0 allocations: 0 bytes)
Julia 代码应始终位于函数内,以便编译器可以对其进行优化。此外,您同时测量编译时间和执行时间:为了获得准确的度量,您应该调用该函数两次(第一次用于编译(。
function test(n)
x=rand(n);
y=rand(n);
mn=ones(n)*1000;
for i in 1:n;
for j in 1:n;
c=abs(x[j]-y[i])
if(c<mn[i])
mn[i]=c
end
end
end
(mn, x, y)
end
test(1)
@time test(5000);
这在我的笔记本电脑上需要 0.04 秒。 Chromium 1s 中的 JavaScript (Firefox Web Console 53s 中的 JavaScript(