Избегайте ненужных копий данных

Передающие значения к функциям

При вызывании функции с входными параметрами MATLAB® копирует значения с рабочей области функции вызова в переменные параметра в вызванной функции. Однако MATLAB применяет различные методы, чтобы не делать копии этих значений, когда это не необходимо.

MATLAB не обеспечивает способ задать ссылку на значение, как на языках как C++. Вместо этого MATLAB позволяет нескольким вывод, а также несколько входных параметров так, чтобы вы знали, какие значения входят в функцию и какие значения выходят из функции.

Копирование при записи

Если функция не изменяет входной параметр, MATLAB не делает копию значений содержавшейся во входной переменной.

Например, предположите, что вы передаете большой массив функции.

A = rand(1e7,1);
B = f1(A);

Функциональный f1 умножает каждый элемент во входном массиве X 1.1 и присваивает результат переменной Y.

function Y = f1(X)
   Y = X.*1.1; % X is a shared copy of A
end

Поскольку функция не изменяет входные значения, локальная переменная, X и переменная A в рабочей области вызывающей стороны совместно используют данные. После того, как f1 выполняется, значения, присвоенные A, не изменились. Переменная B в рабочей области вызывающей стороны содержит результат поэлементного умножения. Вход передается значением. Однако никакая копия не сделана при вызове f1.

Функциональный f2 действительно изменяет свою локальную копию входной переменной, заставляя локальную копию быть неразделенным с входом A. Значение X в функции является теперь независимой копией входной переменной A в рабочей области вызывающей стороны. Когда f2 возвращает результат в рабочую область вызывающей стороны, локальная переменная, X уничтожается.

A = rand(1e7,1);
B = f2(A);
function Y = f2(X)
   X = X.*1.1; % X is an independent copy of A
   Y = X;      % Y is a shared copy of X
end

Передача входных параметров как выражения MATLAB

Можно использовать значение, возвращенное от функции как входной параметр к другой функции. Например, используйте функцию rand, чтобы создать вход для функционального f2 непосредственно.

B = f2(rand(1e7,1));

Единственная переменная, содержащая значение, возвращенное rand, является временной переменной X в рабочей области функционального f2. Нет никакой разделяемой или независимой копии этих значений в рабочей области вызывающей стороны. Непосредственно передающие функциональные выходные параметры экономят время и память, требуемую создать копию входных значений в вызванной функции. Этот подход целесообразен, когда входные значения не используются снова.

Оперативное присвоение

Можно присвоить вывод функции к той же переменной как вход, когда вы не должны сохранять исходные входные значения.

A = f2(A);

Переназначение к тому же имени переменной следует за поведением копирования при записи, описанным ранее: изменение значений входной переменной приводит к временной копии тех значений. Однако MATLAB может применить оптимизацию памяти при определенных обстоятельствах.

Рассмотрите следующий пример. Функция memoryOptimization создает большой массив случайных чисел в переменной A. Затем это вызывает локальную функцию fLocal, передавая A как вход, и присваивая вывод локальной функции к тому же имени переменной.

Поскольку вызов локальной функции, A = fLocal(A), присваивает вывод переменной A, MATLAB не должен сохранять исходное значение A во время выполнения функции. В fLocal вход X имеет единственную копию значения, первоначально сохраненного A.

Поэтому модификации, сделанные к X в fLocal, не приводят к копии данных. Присвоение, X = X.*1.1, изменяет X на месте, не выделяя новый массив для результата умножения.

function memoryOptimization
   A = rand(1e7,1);
   A = fLocal(A);
end
function X = fLocal(X)
   X = X.*1.1; 
end

Устранение копии в локальной функции сохраняет память и улучшает скорость выполнения для больших массивов. Однако MATLAB не может применить оптимизацию памяти, когда возможно использовать переменную после того, как функция выдает ошибку. Поэтому эта оптимизация не применяется в скриптах, на командной строке, в вызовах eval, или кода в блоках попытки/выгоды.

Кроме того, MATLAB не применяет оптимизацию памяти, когда к исходной переменной можно получить доступ непосредственно во время выполнения вызванной функции. Например, если бы fLocal был вложенной функцией, MATLAB не мог бы применить оптимизацию, потому что переменные могут быть совместно использованы с родительской функцией.

Наконец, MATLAB не применяет оптимизацию памяти, когда присвоенная переменная объявляется как глобальная переменная или персистентная.

Почему семантика передачи значением

MATLAB использует семантику передачи значением когда передающие аргументы к функциям и возвращающим значениям от функций. В некоторых случаях передача значением приводит к копиям исходных значений, сделанных в вызванной функции. Однако семантика передачи значением обеспечивает определенные преимущества.

При вызывании функций вы знаете, что входные переменные не изменяются в рабочей области вызывающей стороны. Поэтому вы не должны делать копии входных параметров в функции или на сайте вызова только, чтобы принять меры против возможности, что эти значения могут быть изменены. Только переменные, присвоенные возвращенным значениям, изменяются.

Кроме того, вы избегаете возможности повреждения переменных рабочей области, если ошибка происходит в функции, которая была передана переменная ссылкой.

Обработайте объекты

Существуют специальные виды объектов под названием handles. Все переменные, которые содержат копии того же указателя, могут получить доступ и изменить тот же основной объект. Объекты указателя полезны при специализированных обстоятельствах, где объект представляет физический объект, такой как окно, график, устройство, или человек, а не математический объект как номер или матрица.

Объекты указателя выводят от класса handle, который обеспечивает функциональность, такую как события и прослушиватели, методы деструктора и поддержка динамических свойств.

Для получения дополнительной информации о значениях и указателях, смотрите Сравнение Классов Указателя и Значения и Который Вид Класса Использовать.

Смотрите также

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте