Ответ 1
Тест
Используя MatLab 2013b я и Intel Xeon 3.6GHz + 16GB RAM, я запустил код ниже в профиль. Я выделил 3 метода и рассмотрел только 1D массивы, т.е. Векторы. Методы 1 и 2 были протестированы с использованием как векторов столбцов, так и векторов строк, то есть (n, 1) и (1, n).
Способ 1 (M1R, M1C)
a = zeros(1,n);
Способ 2 M2R, M2C
a = NaN(1,n);
Способ 3 (M3)
a(n) = 0;
Результаты
Результаты синхронизации и количество элементов были нанесены на диаграмму с правильной логарифмической шкалой на рисунке 1D.
Как показано, третий метод имеет назначение, почти не зависящее от размера вектора, в то время как другое неуклонно увеличивается, предполагая неявное определение вектора.
Обсуждение
MatLab делает много оптимизации кода, используя JIT (как раз вовремя), то есть оптимизацию кода во время выполнения. Таким образом, вопрос заключается в том, чтобы определить, действительно ли часть кода работает быстрее из-за программирования (всегда то же, независимо от того, оптимизирована или нет) или из-за оптимизации. Для проверки этой оптимизации можно отключить, используя функцию ( "ускорить", "выключить" ). Результаты запуска кода снова довольно интересны:
Показано, что теперь метод 1 является оптимальным, как для векторов строк и столбцов. И метод 3 ведет себя как другие методы в первом тесте.
Заключение
Оптимизация предопределения памяти бесполезна и пустая трата времени, так как MatLab будет оптимизировать для вас в любом случае.
Обратите внимание, что память должна быть предварительно выделена, но способ, которым вы это делаете, не имеет значения. Производительность предварительно распределяющей памяти во многом зависит от того, хочет ли JIT-компилятор MatLab оптимизировать ваш код или нет. Это полностью зависит от всего другого содержимого вашего .m файла, поскольку компилятор в это время рассматривает куски кодов, а затем пытается оптимизировать (у него даже есть память, так что запуск файла несколько раз может привести к еще более низкому исполнению - время). Кроме того, предварительное распределение памяти чаще всего является очень коротким процессом, рассматривающим производительность по сравнению с выполненным впоследствии вычислением.
По моему мнению, память должна быть предварительно назначена либо с использованием метода 1, либо с помощью метода 2 для поддержания читаемого кода и использования функции, которую предлагает MatLab, поскольку они наиболее вероятно будут улучшены в будущем.
Используемый код
clear all
clc
feature('accel','on')
number1D=30;
nn1D=2.^(1:number1D);
timings1D=zeros(5,number1D);
for ii=1:length(nn1D);
n=nn1D(ii);
% 1D
tic
a = zeros(1,n);
a(randi(n,1))=1;
timings1D(1,ii)=toc;
fprintf('1D row vector method1 took: %f\n',timings1D(1,ii))
clear a
tic
b = zeros(n,1);
b(randi(n,1))=1;
timings1D(2,ii)=toc;
fprintf('1D column vector method1 took: %f\n',timings1D(2,ii))
clear b
tic
c = NaN(1,n);
c(randi(n,1))=1;
timings1D(3,ii)=toc;
fprintf('1D row vector method2 took: %f\n',timings1D(3,ii))
clear c
tic
d = NaN(n,1);
d(randi(n,1))=1;
timings1D(4,ii)=toc;
fprintf('1D row vector method2 took: %f\n',timings1D(4,ii))
clear d
tic
e(n) = 0;
e(randi(n,1))=1;
timings1D(5,ii)=toc;
fprintf('1D row vector method3 took: %f\n',timings1D(5,ii))
clear e
end
logtimings1D = log10(timings1D);
lognn1D=log10(nn1D);
figure(1)
clf()
hold on
plot(lognn1D,logtimings1D(1,:),'-k','LineWidth',2)
plot(lognn1D,logtimings1D(2,:),'--k','LineWidth',2)
plot(lognn1D,logtimings1D(3,:),'-.k','LineWidth',2)
plot(lognn1D,logtimings1D(4,:),'-','Color',[0.6 0.6 0.6],'LineWidth',2)
plot(lognn1D,logtimings1D(5,:),'--','Color',[0.6 0.6 0.6],'LineWidth',2)
xlabel('Number of elements (log10[-])')
ylabel('Timing of each method (log10[s])')
legend('M1R','M1C','M2R','M2C','M3','Location','NW')
title({'Various methods of pre-allocation in 1D','nr. of elements vs timing'})
hold off
Примечание
Строки, содержащие c(randi(n,1))=1
; не делайте ничего, кроме присвоения значения одному случайному элементу в предварительно выделенном массиве, чтобы массив использовался, чтобы немного бросить вызов компилятору JIT. Эти линии не влияют на измерение предварительного распределения значительно, то есть они не измеряются и не влияют на тест.