Why my Julia code runs slower than javascript?

2019-05-05 05:56发布

Recently, I was intrigued by the Julia-lang as it claims to be a dynamic language that has near C performance. However, my experience with it so far is not good (at least performance wise). The application that I'm writing requires random-access to specific array indices and then comparing their values with other specific array indices (over many iterations). The following code simulates my needs from the program: My Julia code finishes executing in around 8seconds while the java-script code requires less than 1second on chrome environment! Am I doing something wrong with the Julia code? Thanks a lot in advance.

Julia code here:

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 code: (>8 times faster than the julia code above!)

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');

2条回答
Ridiculous、
2楼-- · 2019-05-05 06:19

Julia code should always be inside a function, so that the compiler can optimize it. Also, you are measuring both the compile time and the execution time: to get an accurate measure, you should call the function twice (the first for compilation).

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);

This is taking 0.04s on my laptop. javascript in chromium 1s (javascript in firefox web console 53s)

查看更多
走好不送
3楼-- · 2019-05-05 06:27

Performance Tips

Avoid global variables

A global variable might have its value, and therefore its type, change at any point. This makes it difficult for the compiler to optimize code using global variables. Variables should be local, or passed as arguments to functions, whenever possible.

Any code that is performance critical or being benchmarked should be inside a function.

We find that global names are frequently constants, and declaring them as such greatly improves performance:

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)
查看更多
登录 后发表回答