Как минимум внутренний цикл можно заменить на:
M(i)=sum(x<=w(i))
это обеспечит существенное улучшение производительности. Затем вы можете рассмотреть возможность использования arrayfun:
M = arrayfun(@(wi)( sum( x <= wi ) ), w);
arrayfun с меньшей вероятностью даст существенный выигрыш по сравнению с внешним циклом for, но, возможно, стоит попробовать.
edit: я должен отметить, что ни w
, ни x
не нужно сортировать для правильной работы этой операции.
edit: fwiw, я решил провести некоторое тестирование производительности, поэтому запустил эту программу:
n = 100000;
m = n;
N = n + m;
x = rand(n, 1);
w = [x; rand(m, 1)];
tic;
M = zeros(N,1);
for i = 1:N
for j = 1:n
if x(j) <= w(i)
M(i) = M(i) + 1;
end
end
end
perf = toc;
fprintf(1, 'Original : %4.3f sec\n', perf);
w = sort(w); % presorted, so don't incur time cost;
tic;
M = histc(-x(:)',[-fliplr(w(:)') inf]);
M = cumsum(fliplr(M(1:N)))';
perf = toc;
fprintf(1, 'gnovice : %4.3f sec\n', perf);
tic;
M = zeros(N,1);
for i = 1:N
M(i)=sum(x<=w(i));
end
perf = toc;
fprintf(1, 'mine/loop : %4.3f sec\n', perf);
tic;
M = arrayfun(@(wi)( sum( x <= wi ) ), w);
perf = toc;
fprintf(1, 'mine/arrayfun : %4.3f sec\n', perf);
и получил эти результаты для n = 1000:
Original : 0.086 sec
gnovice : 0.002 sec
mine/loop : 0.042 sec
mine/arrayfun : 0.070 sec
и для n = 100000:
Original : too long to tell ( >> 1m )
gnovice : 0.050 sec
mine/loop : too long to tell ( >> 1m )
mine/arrayfun : too long to tell ( >> 1m )