Сохраняю ли я память в MATLAB, объявляя переменные глобальными вместо передачи их в качестве аргументов? - PullRequest
10 голосов
/ 11 августа 2009

Я новичок в MATLAB, его не было в описании работы, и я был вынужден взять на себя ответственность за человека, который написал и поддерживал код, который использует моя компания. Жизнь тяжела.

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

Это правда? Я прочитал Стратегии эффективного использования памяти , и там написано, что

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

Это говорит нечто очень похожее в Распределение памяти для массива # Аргументы функций :

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

Так правда ли, что использование global может быть лучше? Кажется немного неаккуратным, чтобы беспечно объявить все большие данные как global вместо того, чтобы убедиться, что ни один из кодов не изменяет свой входной аргумент. Я ошибся? Это действительно улучшает использование оперативной памяти?

Ответы [ 4 ]

6 голосов
/ 11 августа 2009

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

В Matlab довольно много фольклора по вопросам производительности, и не все это правильно. Внутренние части Matlab сильно изменились. Возможно, в предыдущей версии лучше использовать глобальную переменную.

4 голосов
/ 11 августа 2009

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

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

  • Вы должны сделать заявление, подобное global varName везде, где они вам нужны.
  • Концептуально может быть немного беспорядочно пытаться отслеживать, когда и как они изменены, особенно если они распределены по нескольким m-файлам.
  • Пользователь может легко взломать ваш код с помощью некорректного clear global, который очищает все глобальные переменные.

Альтернатива global переменным была упомянута в первом наборе документации, который вы цитировали : вложенные функции. Сразу после цитируемой вами цитаты приведен пример кода (который я немного отформатировал здесь):

function myfun

  A = magic(500);
  setrowval(400, 0);
  disp('The new value of A(399:401,1:10) is')
  A(399:401,1:10)

  function setrowval(row, value)
    A(row,:) = value;
  end

end

В этом примере функция setrowval является вложенной внутри функции myfun. Переменная A в рабочей области myfun доступна в пределах setrowval (как если бы она была объявлена ​​global в каждой). Вложенная функция изменяет эту общую переменную, избегая, таким образом, дополнительного выделения памяти. Вам не нужно беспокоиться о том, что пользователь случайно что-то очистит, и (на мой взгляд) это немного чище и легче следовать, чем объявление global переменных.

3 голосов
/ 11 августа 2009

Я думаю, что вы в значительной степени ответили на свой вопрос, но здесь вам пригодятся еще пара ссылок:

Я сделал видео по этому поводу:

http://blogs.mathworks.com/videos/2008/09/16/new-location-and-memory-allocation/

Подобно тому, о чем говорила Лорен здесь:

http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/

Догу

3 голосов
/ 11 августа 2009

Решение кажется мне немного странным. Как вы уже узнали, это не должно оказывать существенного влияния на использование памяти, если вызываемая функция не изменяет массив данных. Однако, если вызываемая функция изменяет массив данных, есть функциональная разница: в одном случае (создание массива данных глобальным) изменение влияет на остальную часть кода, в другом случае передавая его в качестве ссылки) изменения являются только локальными и временными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...