Search code examples
performancejuliabenchmarking

Why my Julia code runs slower than javascript?


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

Solution

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