Объяснения хорошей производительности
Matlab использует copy-on-write, когда это возможно. Если вы пишете выражения типа B=A
, MATLAB не копирует A, вместо этого обе переменные A
и B
являются ссылками на одну и ту же структуру данных. Только если одна из двух переменных будет изменена, MATLAB создаст копию.
Теперь к специальному случаю reshape
. Здесь похоже, что A и B не совпадают, но в памяти они есть. Базовый массив, который хранит данные, не зависит от операции reshape
, ничего не нужно перемещать: all(A(:)==B(:))
. Все, что нужно MATLAB при вызове reshape, это создать новую ссылку и аннотировать ее новыми измерениями матрицы. Изменение формы матрицы - это не что иное, как создание новой ссылки на входные данные,, которая аннотируется новыми измерениями. Время выполнения изменения составляет менее 1 мкс или примерно так, как требуется два простых назначения, например B=A
. Для всех практических применений используется операция с нулевым временем.
>> tic;for i=1:1000;B=reshape(A,1024,128,1024);end;toc
Elapsed time is 0.000724 seconds.
>> tic;for i=1:1000;B=A;end;toc
Elapsed time is 0.000307 seconds.
Неизвестно, насколько велика такая ссылка, но мы можем предположить, что она находится в пределах нескольких байтов.
Другие операции нулевой стоимости
Функции, известные имеют практически нулевой стоимости (как во время выполнения и памяти):
B=reshape(A,sz)
B=A(:)
B=A.'
- только для векторов
B=A'
- только для Векторы действительных чисел, without the attribute complex
. Вместо этого используйте .'
.
B=permute(A,p)
- только для случаев, когда all(A(:)==B(:))
.
B=ipermute(A,p)
- только для случаев, когда all(A(:)==B(:))
.
B=squeeze(A)
shiftdim
- только для тех случаев, когда all(A(:)==B(:))
, которые являются:
- используется для удаления ведущих одноэлементные размеров.
- используется с отрицательным вторым входом
- используется без ввода второго аргумента.
Функции, которые являются "дорогими", независимо от того, что они не трогают представление в памяти (all(A(:)==B(:))
верно)
- левосторонний индексацию:
B(1:numel(A))=A;
- Правостороннее индексирование, отличное от
(:)
, включая B=A(1:end);
и B=A(:,:,:);
значительно медленнее, чем во время выполнения reshape
между 1 мкс и 1 мс. Вероятно, из-за каких-то постоянных издержек вычислений. Потребление памяти практически равно нулю, а время выполнения не зависит от размера ввода. Операции без этой аннотации имеют продолжительность работы менее 1 мкс и примерно эквивалентны reshape
.
Нулевая стоимость в OCTAVE