"GLOBAL может быть очень неэффективным"
Я использую (в Matlab) global
оператор внутри команды if, так что я импортирую глобальную переменную в локальное пространство имен, только если она действительно нужна.
Анализатор кода предупреждает меня об этомglobal
может быть очень неэффективным, если это не оператор верхнего уровня в своей функции ". Размышляя о возможной внутренней реализации, я нахожу это ограничение очень странным и необычным. Я думаю о двух возможностях:
Что на самом деле означает это предупреждение?
global
очень неэффективен сам по себе, поэтому не используйте его в цикле ". В частности, использование его внутри if, как я делаю, совершенно безопасно, и предупреждение выдается неправильно (и плохо сформулировано)Предупреждение верно; Matlab использует какой-то действительно необычный механизм загрузки переменных в фоновом режиме, поэтому он значительно медленнее импортирует глобальные переменные внутри оператора if. В этом случае я хотел бы получить подсказку или указатель на то, как эти вещи действительно работают, потому что мне это интересно, и мне кажется важным, если я хочу написать эффективный код в будущем.
Какое из этих двух объяснений является правильным? (а может и нет?)
Заранее спасибо.
РЕДАКТИРОВАТЬ: чтобы прояснить: я знаю, что global
медленный (и, очевидно, я не могу избежать его использования, так как это решение по дизайну старой библиотеки, которую я использую); я спрашиваю, почему анализатор кода Matlab жалуется на
if(foo==bar)
GLOBAL baz
baz=1;
else
do_other_stuff;
end
но не о
GLOBAL baz
if(foo==bar)
baz=1;
else
do_other_stuff;
end
Мне трудно представить причину, по которой первое должно быть медленнее, чем второе.
4 ответа
Ответ Уолтера Роберсона здесь http://mathworks.com/matlabcentral/answers/19316-global-could-be-very-inefficient
[...] Это не обязательно большая работа, если она не выполняется в команде верхнего уровня, но люди склонны помещать конструкцию в цикл или в несколько неисключительных мест в условных структурах. Человеку, пишущему мельничные предупреждения, гораздо проще не добавлять пояснения вроде: "Если вы не докажете, что эти" глобальные "будут выполняться только один раз, в этом случае это не менее эффективно, но все равно является плохой формой"
поддерживает мой вариант (1).
В дополнение к сообщению эйканала, эта техническая заметка объясняет, почему глобальный процесс медленный.
... когда вызов функции включает в себя глобальные переменные, производительность еще более снижается. Это связано с тем, что для поиска глобальных переменных MATLAB должен расширить свое пространство поиска за пределы текущего рабочего пространства. Более того, причина, по которой вызов функции с глобальными переменными выглядит намного медленнее, чем у других, заключается в том, что MATLAB Accelerator не оптимизирует такой вызов функции.
Я не знаю ответа, но я сильно подозреваю, что это связано с тем, как память выделяется и распределяется во время выполнения.
Как бы то ни было, я рекомендую прочитать следующие две записи в блогах Mathworks Лорен и Дуга:
- Написание развертываемого кода, самое первое, что он пишет в этом посте
- Лучшие 10 практик кода MATLAB, которые заставляют меня плакать, #2 в этом списке.
Короче говоря, глобальные переменные почти никогда не выходят; Есть много других способов обеспечить совместное использование переменных - некоторые из которых она обсуждает - которые более эффективны и менее подвержены ошибкам.
Факт (с Matlab 2014 до Matlab 2016a, без использования набора инструментов Parallell): часто самым быстрым кодом, который вы можете получить с помощью Matlab, является выполнение вложенных функций, совместное использование переменных между функциями без их передачи.
Шаг, близкий к этому, - использование глобальных переменных и разбиение вашего проекта на несколько файлов. Это может немного снизить производительность, потому что (предположительно, хотя я никогда не видел, чтобы это проверялось ни в одном тесте), Matlab переносит накладные расходы, извлекая из глобального рабочего пространства, и потому, что существует какая-то проблема (предположительно, хотя я никогда не видел никаких доказательств этого)) с ускорением JIT.
Благодаря моему собственному тестированию передача очень больших матриц данных (изображений высокого разрешения) между вызовами функций с использованием вложенных функций или глобальных переменных практически идентична по производительности.
Причина того, что вы можете добиться превосходной производительности с помощью глобальных переменных или вложенных функций, заключается в том, что вы можете избежать копирования дополнительных данных таким образом. Если вы отправляете переменную в функцию, Matlab делает это по ссылке, но если вы изменяете переменную в функции, Matlab делает копию на лету (копирование при записи). Я не знаю, как избежать этого в Matlab, кроме как с помощью вложенных функций и глобальных переменных. Любая небольшая утечка, которую вы получаете от помех к JIT или глобальному времени выборки, полностью достигается за счет избежания этого дополнительного копирования данных (при использовании больших данных).
Это, возможно, изменилось с никогда не версиями Matlab, но из того, что я слышу от друзей, я сомневаюсь в этом. Я не могу сдать ни одного теста, у меня больше нет лицензии Matlab.
В качестве доказательства, посмотрите не дальше, чем этот набор инструментов для обработки видео, который я создал еще в тот день, когда работал с Matlab. Это ужасно уродливо под капотом, потому что у меня не было способа получить производительность без глобалов.
Тот факт, что Matlab (глобальные переменные являются наиболее оптимизированным способом кодирования, когда вам необходимо изменить большие данные в различных функциях), указывает на необходимость обновления языка и / или интерпретатора.
Вместо этого Matlab мог бы использовать лучшее, более динамичное понятие рабочего пространства. Но ничто из того, что я видел, не указывает на то, что это когда-нибудь случится. Особенно, когда вы видите, что сообщество пользователей, по-видимому, игнорирует факты и выдвигает противоположности безо всякой основы: например, использование глобалов в Matlab идет медленно.
Они не.
Тем не менее, вы не должны использовать глобалы, никогда. Если вы вынуждены выполнять обработку видео в реальном времени в чистом Matlab, и вы обнаружите, что у вас нет другого выбора, кроме использования глобалов для достижения производительности, вы должны получить подсказку и сменить язык. Пришло время перейти к языкам с более высокой производительностью... а также, возможно, написать случайные разглагольствования о переполнении стека, в надежде, что Matlab может быть улучшен за счет влияния на мнение своих пользователей.