2014-11-26 11 views
5

Ponieważ Matlab jest interpretowany, zwykle spędza dużo czasu na początku funkcji wymuszającej podpis funkcji. Na przykład:Kiedy używać assert() w Matlabie?

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') ... 

Czy zamiast tego lepiej jest użyć Matlab's assert()? Jeśli nie, kiedy jest odpowiedni czas na użycie assert() w Matlabie?

Istnieje świetna dyskusja na temat używania assert w kodzie produkcyjnym here, ale nie jestem pewien, czy dotyczy to kodu interpretowanego. Podobnie, kolejna dobra dyskusja here i zgadzam się z @Dan Dyer odnośnie asercji, aby wyrazić przekonanie o obecnym stanie. Jednak patrząc na podobną dyskusję dla Pythona here ludzie mówią, używaj tylko asertu dla sytuacji, które nigdy nie powinny się zdarzyć (jak wyjątki w wyjątkowych przypadkach), co jest trochę sprzeczne w.r.t. poprzednie referencje.

Być może jest to bardziej pytanie o rolę asertu w interpretowanych językach, a mniej o Matlab.

+0

Piszę kod matlab, aby wykonać wiele prototypów. Nie jestem pewien, jaki jest "właściwy" przypadek użycia, ale zasadniczo idę z interpretacją wiary w aktualny stan i używam ich często. Nie zauważyłem problemów z wydajnością podczas profilowania w dowolnej rozsądnie nowej wersji programu Matlab. Lubię ich czystość w kodzie do częstego sprawdzania zachowania. Jednak rzadko robię kod produkcyjny w Matlab :) – adalca

Odpowiedz

3

W przeważającej części, nie ma różnicy między

assert(X,...) 

i

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

a wybór między nimi jest to kwestia wygody i stylu.

Rozróżnienie między kodem nieprodukcyjnym a kodem produkcyjnym w projektach opartych na platformie MATLAB często nie jest takie samo, jak rozróżnienie w projektach opartych na innych językach.

Jest to częściowo dlatego, że jak mówisz, MATLAB jest zwykle interpretowany, a nie kompilowany; chociaż możliwe jest tworzenie aplikacji przy użyciu kompilatora MATLAB lub produktów Buildera, które, choć nie są ściśle "skompilowane", nie mają widocznego kodu źródłowego i nie mogą być debugowane.W przypadku tego rodzaju aplikacji trzeba obsługiwać wyjątki i błędy tak dokładnie, jak w przypadku skompilowanego języka.

Częściowo dlatego, że "produkcja" często oznacza coś innego w przypadku projektów wykorzystujących MATLAB niż w przypadku projektów w innych językach; na przykład może to oznaczać, że kod MATLAB jest automatycznie konwertowany na C w celu wdrożenia do kontrolera silnika samochodowego, lub może to oznaczać, że jakiś kod MATLAB uruchamiał model prognozowania finansowego i zapisywał wyniki w produkcyjnej bazie danych.

Istnieje specjalny przypadek, w którym należy używać assert, a nie if..error..end, czyli gdy używasz programu MatLAB Coder do generowania kodu C z kodu MATLAB. MATLAB Coder sprawdza instrukcje assert w kodzie MATLAB, aby wywnioskować właściwości zmiennych, które musi przekonwertować na C, i może wygenerować lepszy kod C, jeśli może przyjąć fakty o zmiennych, które potwierdzasz (takie jak rozmiary i typy macierzy).

Ostatni punkt: dla określonej aktywności, o której wspomniałeś, wymuszając podpis funkcji, nie używałbym żadnej z tych metod - inputParser jest zazwyczaj bardziej niezawodny i spójny (choć nieco gadatliwy), ale co ważniejsze zachęca do zaprojektowania funkcji podpisuj się dobrze w pierwszej kolejności.

+0

Jak nigdy nie słyszałem o inputParser ?! Świetne informacje, bardzo doceniane. –

2

Sposób MATLAB obsługuje twierdzeń oznacza, że ​​z punktu widzenia użytkownika, nie ma różnicy między stwierdzeniami:

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

i

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

Zarówno wynik w tej samej mocy wyświetlane użytkownikowi i te same dane są przechowywane w lasterr. Oba są przechwytywane przez blok try-catch. Opierając się na bardzo szybkim i brudnym teście, próbowałem twierdzić, że assert jest ~ 5% wolniejsze niż error (chociaż to naprawdę nie robi wielkiej różnicy w dużym schemacie rzeczy). W rezultacie jedyną istotną różnicą jest programista/opiekun kodu, co czyni go w dużej mierze wyborem stylistycznym.

Zarówno assert, jak i error mają swoje za i przeciw. assert wygląda nieco czystsze i zajmuje mniej miejsca, ale nie jest konieczne, jak oczywiste, co dzieje się na pierwszy rzut oka. Dla mojego osobistego użytku wolałbym skrzynkę error, ponieważ mogę umieścić punkt przerwania na linii z wywołaniem błędu, a tam się złamie, jeśli błąd zostanie zgłoszony - nie można tego zrobić tak łatwo jak z komunikatem assert (można użyć dbstop in file if error, ale potencjalnie ma to swoje problemy). Mogę również wstawić kod debugowania do if-statement, aby wydrukować informacje o stanie programu, zanim zostanie zgłoszony błąd.

2

Inną perspektywą tego problemu jest czas pracy. Zazwyczaj oczekuje się, że kod będzie działał bezbłędnie. Oznacza to, że nie dbasz o milisekundy, które zajmuje Matlab, aby wyprodukować błąd, ale tylko test logiczny.

oto kod użyłem do porównania:

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; 

teraz, niech uruchomić tę funkcję tyle razy, aby uzyskać dobre statystyki:

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

i wyniki:

ans =

1.0e-05 *

0,0088 0,3548

dolna linia:

assert jest dużo bardziej powolny niż if-else.