2015-05-05 3 views
3

Если у нас есть две матрицыи Y, то оба эти размера, математически можно сказать: sum(X-Y)=sum(X)-sum(Y).matlab sum (X-Y) vs sum (X) - sum (Y)

Что более эффективно в Matlab? Что быстрее?

+3

как насчет бенчмаркинга с использованием 'tic' и' toc'? –

+0

@ м.с. sum (X-Y) немного быстрее, чем sum (X) -sum (Y), hmmmmm вроде ответил на мой вопрос, так или иначе, почему? – niceman

+0

как вы точно оценили? вы должны ежемесячно измерять время выполнения в цикле (например, 1000) и сравнивать результаты. –

ответ

11

На моей машине sum(x-y) немного быстрее для небольших массивов, но sum(x)-sum(y) довольно много быстрее для больших массивов. Для сравнения я использую MATLAB R2015a на компьютере под управлением Windows 7 с памятью 32 ГБ.

n = ceil(logspace(0,4,25)); 

for i = 1:numel(n) 
    x = rand(n(i)); 
    y = rand(n(i)); 
    t1(i) = timeit(@()sum(x-y)); 
    t2(i) = timeit(@()sum(x)-sum(y)); 
    clear x y 
end 

figure; hold on 
plot(n, t1) 
plot(n, t2) 
legend({'sum(x-y)', 'sum(x)-sum(y)'}) 
xlabel('n'); ylabel('time') 
set(gca, 'XScale', 'log', 'YScale', 'log') 

enter image description here

+0

ха-ха ... к тому времени, когда я закончил редактирование своего сообщения, ваше уже было! Хорошая работа, они показывают те же результаты (хотя ваш кроссовер, похоже, происходит еще раньше ...) – Hoki

+0

Приятно видеть сюжеты! – Divakar

+0

Итак, если «sum» и «X-Y» векторизованы, и оба они выполняют операции по всем X и всем Y, в чем причина разницы во времени? –

6

Вы меня все любопытно и я решил запустить некоторые тесты. К тому времени, как я закончил, кажется, что knedlsepp имеет это право, так как для больших матриц sum(X-Y) становится довольно медленным.

Кроссовер, похоже, происходит около 10^3 элементов.

img1

%% // Benchmark code 

nElem = (1:9).'*(10.^(1:6)) ; nElem = nElem(:) ; %'//damn pretifier 
nIter = numel(nElem) ; 

res = zeros(nIter,2) ; 
for ii=1:nIter 
    X = rand(nElem(ii) ,1) ; 
    Y = rand(nElem(ii) ,1) ; 

    f1 = @() sum(X-Y) ; 
    f2 = @() sum(X)-sum(Y) ; 

    res(ii,1) = timeit(f1) ; 
    res(ii,2) = timeit(f2) ; 
    clear f1 f2 X Y 
end 

loglog(nElem,res,'DisplayName','nElem') 

Я побежал, что несколько раз, и результаты вполне согласуются на моей машине. Я взорвал свою память, пытаясь выйти выше 10^7 элементов. Не стесняйтесь продлить тест, но я не думаю, что отношения будут сильно меняться.


функции: Windows 8.1 Pro/Matlab R2013a на: specs

2

Предполагая, что оба х и у имеют N элементов х M = K, то Для суммы (х) -сумма (у) у вас есть :

K доступ к памяти для чтения x, доступ к памяти K для чтения y, один доступ к памяти для записи результата -> 2K + 1 доступ к памяти (Предполагая, что промежуточная сумма внутри функции суммы будет удерживаться в CPU регистр).

2K суммы операций + вычитание 1 -> 2k + 1 операций ЦП.

Для суммы (x - y): Matlab будет вычислять x - y и хранить результат, а затем вычислять сумму, поэтому у нас есть доступ к памяти K для чтения x, доступ к памяти K для чтения y, доступ к памяти K для записи результат вычитания, доступ к памяти K для повторного считывания результата вычитания для функции sum, затем 1 доступ к памяти для записи результата суммы -> 4K + 1 операций с памятью.

k вычитания + k суммирования -> 2K операций.

Как мы видим, сумма (x - y) потребляет много памяти, поэтому в большом количестве элементов она может потреблять более высокое время, но у меня нет объяснения, почему она быстрее для небольшого количества элементов.

+0

Хорошее объяснение - на первый взгляд - противоречивые результаты других ответов! –

+0

Можете ли вы оценить среднее время для операции доступа к памяти и операцию двойной точности плюс/минус в цикле процессора или на такой стандартной архитектуре, как i7? Я думаю, размер кэша процессора должен иметь эффект? –

+0

Кстати, хотя я уважаю ваше желание написать свое имя в вашем родном скрипте, это затрудняет вам работу, по крайней мере, для кого-то, не имеющего обширных знаний об арабском. –