Ответ 1
Объяснение хорошей производительности
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'
- только для векторов действительных чисел без атрибутаcomplex
. Вместо этого используйте.'
. -
B=permute(A,p)
- только для случаев, когдаall(A(:)==B(:))
. 1 -
B=ipermute(A,p)
- только для случаев, когдаall(A(:)==B(:))
. 1 -
B=squeeze(A)
1 -
shiftdim
- только для случаев, когдаall(A(:)==B(:))
, которые: 1- используется для удаления ведущих размеров синглтона.
- используется с отрицательным вторым входом
- используется без ввода второго аргумента.
Функции, которые являются "дорогими", независимо от того, что они не касаются представления в памяти (all(A(:)==B(:))
истинно)
- Левая односторонняя индексация:
B(1:numel(A))=A;
2 - Правостороннее индексирование, отличное от
(:)
, включаяB=A(1:end);
иB=A(:,:,:);
2
1 Значительно медленнее время выполнения, чем reshape
между 1μs и 1ms. Вероятно, из-за каких-то постоянных издержек вычислений. Потребление памяти практически равно нулю, а время выполнения не зависит от размера ввода. Операции без этой аннотации имеют время работы менее 1 мкс и примерно эквивалентны reshape
.
2 Нулевая стоимость в OCTAVE