Когда использовать assert () в Matlab?

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

if nargin ~= 2; error('must provide two input args a and b'); end
if a < 0||a ~=floor(a); error('input arg1 must be positive non-zero integer'); end 
if ~isa(b,'cell') ...

лучше ли использовать matlab's assert () для этого? Если нет, то когда подходящее время для использования assert() в Matlab?

существует большое обсуждение использования assert в производственном коде здесь но я не уверен, что это относится к интерпретируемым кодом. Аналогично, еще один хороший обсуждение здесь и я согласен с @Dan Dyer относительно assert, чтобы выразить веру в текущее состояние. Однако, глядя на аналогичное обсуждение для Python здесь люди говорят, только используйте assert для ситуаций, которые никогда не должны произойти (например, исключения для исключительных случаев), что немного противоречиво.r.т. предыдущие ссылки.

возможно, это больше вопрос о роли assert играет в интерпретируемых языках и меньше о Матлаб.

3 ответов


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

assert(X,...)

и

if (~X)
    error(...)
end

и ваш выбор между ними-вопрос удобства или стиля.

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

это отчасти потому, что, как вы говорите, MATLAB обычно интерпретируется, а не компилируется; хотя это возможно создавайте приложения с помощью компилятора MATLAB или продуктов Builder, которые, хотя и не являются строго "скомпилированными", не имеют видимого исходного кода и не могут быть отлажены. Для таких приложений вам нужно будет обрабатывать исключения и ошибки так же тщательно, как и для скомпилированного языка.

это также отчасти потому, что "производство" часто означает что-то другое для проектов, которые используют MATLAB, чем для проектов на других языках; например, это может означать, что Код MATLAB автоматически преобразуется в C для развертывания на контроллере двигателя автомобиля, или это может означать, что какой-то код MATLAB запускает модель финансового прогнозирования и записывает результаты в производственную базу данных.

существует особый случай, когда assert а не if..error..end, когда вы используете кодер MATLAB для генерации кода C из кода MATLAB. Кодер MATLAB проверяет assert операторы в коде MATLAB для вывода свойств переменных, которые необходимо преобразовать и может генерировать лучший код C, если он может принимать факты о переменных, которые вы утверждаете (например, размеры и типы массивов).

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


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

if error_check == false
    error('function:state','Error message');
end

и

assert(error_check==false,'function:state','Error message');

оба результата в том же выводе, показанном пользователю, и те же данные хранятся в lasterr. Оба пойманы try-catch заблокировать. Основываясь на очень быстром и грязном тесте, я бы предварительно заявил, что assert ~5% медленнее, чем error (хотя это действительно не имеет большого значения в большом схема вещей.) В результате единственное реальное различие заключается в программисте / сопровождающем коде, что делает его в значительной степени стилистическим выбором.

и assert и error есть свои плюсы и минусы. assert выглядит немного чище и занимает меньше места, но это не обязательно так очевидно, что происходит на первый взгляд. Для моего личного использования, я бы предпочел error case, потому что я могу поставить точку останова на линии с вызовом ошибки, и она будет только ломаться там, если ошибка собирается быть брошен - это не может быть сделано так же легко ,как с сообщением assert (вы можете использовать dbstop in file if error, но это потенциально имеет свои собственные проблемы). Я также могу вставить код отладки в if-statement для вывода информации о состоянии программы, перед ошибка.


другой перспективой для этой проблемы является время выполнения. Обычно вы ожидаете, что ваш код будет работать без ошибок. Это означает, что вы не заботитесь о миллисекундах, которые требуется Matlab, чтобы вызвать ошибку, но только логический тест.

вот код, который я использовал для сравнения:

function o=test

a = 2;
o = [0 0];

tic;
if a~=2
error('a is not 2')
end
o(1) = toc;


tic
assert(a==2,'a is not 2')
o(2) = toc;

теперь, давайте запустим эту функцию достаточно раз, чтобы получить хорошую статистику:

for i=1:10000
o(i,:) = test;
end
mean(o)

результаты:

ans =

1.0 e-05 *

0.0088 0.3548

нижняя строка:

assert намного медленнее, чем if-else.