Почему мой код Джулии работает медленнее, чем JavaScript? - PullRequest
0 голосов
/ 02 мая 2018

Недавно я был заинтригован Julia-lang, так как он претендует на то, чтобы быть динамическим языком с производительностью, близкой к C. Однако мой опыт работы с ним пока не очень хороший (по крайней мере, с точки зрения производительности). Приложение, которое я пишу, требует произвольного доступа к определенным индексам массива, а затем сравнивает их значения с другими конкретными индексами массива (в течение многих итераций). Следующий код имитирует мои потребности из программы: Мой код Julia завершается за 8 секунд, в то время как код java-скрипта требует меньше 1 секунды в среде chrome! Я делаю что-то не так с кодом Джулии? Заранее большое спасибо.

Юлия код здесь:

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 код: (> в 8 раз быстрее, чем код julia выше!)

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 ]

0 голосов
/ 02 мая 2018

Советы по повышению производительности

Избегать глобальных переменных

Глобальная переменная может иметь свое значение и, следовательно, тип, изменить в любой точке. Это мешает компилятору оптимизировать код с использованием глобальных переменных. Переменные должны быть локальными или передаваться как аргументы функций, когда это возможно.

Любой код, который критичен к производительности или проверен внутри функции.

Мы находим, что глобальные имена часто являются константами, и объявляем их как таковой значительно улучшает производительность:

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)
0 голосов
/ 02 мая 2018

Код Джулии всегда должен быть внутри функции, чтобы компилятор мог ее оптимизировать. Кроме того, вы измеряете как время компиляции, так и время выполнения: чтобы получить точный показатель, вы должны вызвать функцию дважды (первый для компиляции).

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 с на моем ноутбуке. JavaScript в хроме 1с (JavaScript в веб-консоли Firefox 53s)

...