2008-11-30 17 views
8

Podaj mi niektóre z twoich przemyśleń na temat, która jest lepszą praktyką kodowania/sprawia, że ​​bardziej wydajny kod/wygląda ładniej/cokolwiek: Zwiększenie i poprawienie umiejętności korzystania z instrukcji, aby przewidywać i wychwytywać potencjalne problemy? A może po prostu dobrze wykorzystujesz try/catch w ogóle?Dokładne użycie instrukcji "if" lub bloków "try/catch"?

Powiedzmy, że to jest dla Javy (jeśli to ma znaczenie).

Edit: Jestem obecnie przejście siebie z dala od niektórych wprawdzie przestarzały i ograniczonych obecnych praktyk kodowania, ale jestem trochę rozdarty na konieczność robi tak na kilka punktów (takich jak ten). Po prostu pytam o kilka perspektyw na ten temat. Nie debata.

Odpowiedz

1

My 2p: Korzystanie try/catch jest najlepszy:

  • to sprawia, że ​​absolutnie jasne dla innych programistów, że robisz wyjątek obsługi
  • kompilator rozumie, co robisz i może wykonywać bardziej odpowiedniej kompilacji -time sprawdza dla ciebie

Z mojego doświadczenia wynika, że ​​użycie logiki warunkowej sprawia, że ​​trudniej jest odróżnić obsługę błędów od logiki biznesowej.

+0

"Obsługa błędów" i "Obsługa wyjątków" to nie to samo. – ThunderGr

4

if bloki są nieco szybsze; jeśli nie potrzebujesz ich kilkunastu, są lepszym pomysłem niż try/catches. Wyjątki powinny być wyjątkowe, nie za każdym razem, gdy kod jest uruchamiany. Używam wyjątków w przypadku rzadkich zdarzeń, takich jak rozłączenia serwerów (mimo że zdarzają się one kilka razy każdego dnia) i bloków if dla dowolnych kontrolowanych zmiennych.

+1

Jeśli/else jest na ogół szybszy niż try/catch, ale jest wolniejszy niż żaden kod w ogóle. Jeśli masz kilka poziomów głębokości połączenia, to jeśli/else na każdej stronie wywołania, aby propagować błędy według wartości zwracanej, może być wolniejsze niż pojedyncze próbowanie/przechwytywanie u góry w przypadku, gdy błąd nie występuje. –

2

myślę if są lepsze. Nie można objąć każdej linii kodu próbą..catch (cóż, możesz, ale nie powinieneś tego robić). Możesz otoczyć blok kodu za pomocą catch, ale nie każdej linii.

Wyjątki spowalniają działanie.

+2

Wyjątki tylko spowalniają działanie, gdy są rzucane. Tak długo, jak upewnisz się, że są one wyrzucane tylko w wyjątkowych okolicznościach (gdzie wydajność zwykle nie ma znaczenia, ponieważ masz awarię), nie jest to problemem. –

+0

@Steve Jessop Jeśli próba/catch jest wolniejsza niż instrukcja if, wyjątki spowalniają działanie, nawet jeśli nie są generowane (w porównaniu do instrukcji if, to znaczy). W końcu blok try/catch musi sprawdzić, czy wyjątek został zgłoszony w tej części kodu. – ThunderGr

+1

@ThunderGr: zależy to od języka programowania i implementacji (oczywiście), ale w przypadku języków skompilowanych * nie * jest konieczne, aby blok try/catch sprawdzał, czy wyjątek został zgłoszony w tym miejscu kodu. Zamiast tego wszystkie bloki przechwytujące można wyciągnąć poza linię (powiedzmy, zebrać je na końcu funkcji lub nawet na końcu pliku wykonywalnego), wraz z niektórymi metadanymi dotyczącymi regionów kodu objętych odpowiednimi próbami. Dostęp do tego kodu/danych jest możliwy tylko wtedy, gdy zostanie zgłoszony wyjątek, a środowisko wykonawcze podejmie stos. –

3

Bez względu na to, jaki kod napiszesz, wykorzystasz oba. Nie mogę mówić za środowisko wykonawcze Java, ale w środowisku wykonawczym .NET występuje trafienie wydajności związane z korzystaniem z bloków try-catch. W rezultacie staram się używać ich tylko w obszarach, w których mam wyraźny sposób na obsługę wyjątku, gdy zostanie on złapany (nawet jeśli jest to rejestracja problemu).

Jeśli używasz wielu bloków try-catch lub bloków-else w swoim kodzie lub twoje metody wydają się być dość długie, rozważ refaktoryzację kodu na większą liczbę mniejszych metod. Intencja logiki będzie łatwiejsza do wykonania - a także łatwiejsza w testowaniu jednostkowym.

1

Z tego, co mi mówili bardziej doświadczeni programiści i analitycy, try/catch jest bardziej zorientowany obiektowo i jeśli jest bardziej proceduralny.

Ja osobiście mnie to nie obchodzi.

Jestem świadomy faktu, że try/catch jest wolniej i powoduje spadek wydajności, ale jeśli mam zamiar użyć tuzin IFS do sprawdzania przed mogę robić, co chcę zrobić, będę zawsze użyj polecenia try/catch, aby zapisać liczbę linii kodu.

To sprawia, że ​​moje życie jest o wiele łatwiejsze, aby nie musiał niczego weryfikować, a jeśli oświadczenie nie powiedzie się, po prostu rób to, co bym zrobił w moim bloku "else" ... w moim bloku "catch".

Czasami oczywiście zamykam niektóre instrukcje if w próbie/catch, ale i tak.

Używam, jeśli jest tylko kilka rzeczy do sprawdzenia (1 lub 2), zanim zrobię to, co muszę zrobić.

+0

Na koniec odpowiedź, która mówi o skutecznym przekazywaniu pomysłów i ułatwianiu zrozumienia i kodowania. Czuję, że wiele odpowiedzi na tej stronie zapomina o tym ważnym fakcie o kodowaniu i mówieniu o kodzie w idealnym świecie. Odpowiedzi te zazwyczaj dostarczają wskazówek dotyczących najlepszych praktyk na temat prędkości biegu lub bezpieczeństwa, ale nie biorą pod uwagę pytania i czy takie rozwiązanie ma sens. Najlepsze praktyki są zazwyczaj szybkie i łatwe, ale w rzeczywistych przypadkach powstają przypadki, w których praktyki te mogą stać się długie i skomplikowane; i potrzebne jest uproszczenie kodu –

0

Jest jedna rzecz, o której tu nie wspomniano.

W przypadku instrukcji if-else za każdym razem, gdy kod jest uruchamiany, co najmniej jeden z warunków jest gwarantowany do oceny. Jestem pewien, że wszyscy wiemy, jak działa if-else-elseif, ale dla jasności ... część instrukcji będzie zawsze oceniana, jeśli jest fałszywa, to następnie oceniany jest następujący , jeśli:, i tak dalej, aż do oceny pozostanie tylko , inaczej.

Używanie instrukcji if-else wpłynie na wydajność. Nieistotnie (w większości przypadków), ale przeprowadzenie oceny zajmuje czas procesora.

Wyrażenia try-catch i popraw mnie, jeśli się mylę, nie są brane pod uwagę w czasie wykonywania, dopóki nie są wymagane (tzn. Wyjątek został zgłoszony). Więc po prostu zawijanie kodu w try-catch nie wpłynie na wydajność, dopóki nie zostanie przez nią przechwycony wyjątek.

Ponadto, nie jest to haczyk, który powoduje uderzenie wydajności, ale rzut.

Jednym z głównych punktów, o których należy pamiętać to, że instrukcje try-catch nie powinny być NIGDY używane w logice warunkowej. Powinny być używane tylko do tego, do czego są przeznaczone: obsługa wyjątków!

Łapanie wyjątków jest niezbędne, jeśli wiesz, co z nimi zrobić. Jeśli nie masz możliwości prawidłowej obsługi wyjątku, powinieneś pozwolić mu odejść, ponieważ jakiś kod w górę łańcucha może mieć lepszy sposób na obsłużenie go.

Zazwyczaj dobrym pomysłem jest posiadanie handlarza wyjątkami na absolutnym najwyższym poziomie aplikacji, aby wychwytywać wyjątki, zanim zostaną zauważone przez użytkownika. W ASP.NET można to zrobić w zdarzeniu Application_Error pliku global.asax. W innych językach/środowiskach zrobiłbyś to w swojej głównej pętli, cokolwiek by to nie było.

Należy jednak pamiętać, że są pewne wyjątki, które zawsze najlepiej pozostawić niezatłoczone. Czasami, gdy wystąpi wyjątek, oznacza to, że stan aplikacji został poważnie naruszony i nie można mu ufać. Jedyną bezpieczną rzeczą do zrobienia jest zabicie i ponowne uruchomienie.

+0

Jak można powiedzieć, że próba/catch * nie jest rozważana w czasie wykonywania, dopóki nie jest wymagana *? To brzmi jak rodzaj magii programowania. Nie ma czegoś takiego jak kod, który * nie jest brany pod uwagę, dopóki nie będzie potrzebny *. Musisz mieć co najmniej * sprawdzenie, czy jest to potrzebne, czy nie. – ThunderGr

+0

Odpowiedź Steve'a powyżej, według mojego komentarza, dostarcza uzasadnionego wyjaśnienia, dlaczego blok try/catch nie byłby w ogóle brany pod uwagę, dopóki nie wystąpi wyjątek.To wymaga jednak uruchomienia maszyny wirtualnej i wygląda na to, że * runtime * języków zapewniają tę maszynę wirtualną. Wątpię, by architektura procesora miała jakąkolwiek obsługę wyjątków. Czy to? – ThunderGr

+0

@ThunderGr Nie mogę mówić za wszystkie języki, ale mikesigs jest poprawne przynajmniej w tym, jak C++ obsługuje wyjątki. W C++ część przechwytująca bloku jest ignorowana, dopóki wyjątek nie zostanie zgłoszony, a stos zaczyna się rozwijać. Po rozwinięciu stosu kod wyszukuje blok catch, aby zatrzymać proces rozwijania. Jeśli nie zostanie znaleziony żaden, który może wyłączyć wyjątek. program wychodzi. –

0

@PersonalPerson - Przepraszam, ale to tylko leniwe kodowanie. Zamiast korzystać z try-catch, ponieważ jest zbyt wiele instrukcji if, może warto zreorganizować swój kod (tj. Umieścić swoją logikę walidacji we własnej metodzie). Dzięki temu Twój kod stanie się bardziej przejrzysty i czytelny, a także zachowa najlepsze praktyki dotyczące wydajności.

Nigdy nie próbuj pisać kodu, aby uzyskać co najmniej # linii. To zawsze kończy się źle. Pewnie, że możesz znaleźć bardziej elegancki sposób na napisanie czegoś, co twoi koderzy-kumple zrobią, ahah, ale to sprawia, że ​​rzeczy stają się mniej czytelne.

Przysięgam, wcześniej pracowałem z twoim kodem i to bolało mnie.

+0

Niestety to stwierdzenie naprawdę zależy od języka. W niektórych językach posiadających instrukcję if z wieloma testami, takimi jak 6 lub 10+ testów, gdzie instrukcja if będzie nazywać się 90 +% czasu, może wymagać dużej ilości czasu procesora w zależności od tego, jak kod jest zoptymalizowany. W takim przypadku użycie bloku catch próby powie zarówno procesorowi, jak i innym programistom, że jest to kod, który chcę uruchomić przez większość czasu, co może potencjalnie zwiększyć szybkość działania w zależności od języka. W każdym innym przypadku zgadzam się z tobą, chyba że używasz języka pisanego kaczką, takiego jak python. –

0

Używanie wyjątków jest uniwersalną metodą powiadamiania innych części kodu o tym, że coś złego stało się luźno powiązanym sposobem. Wyobraźmy sobie, że jeśli chciałbyś poradzić sobie z jakimś wyjątkowym stanem, używając if .. nad else .. musisz wstawić do innej części kodu jakieś dowolne zmienne i inne rzeczy, które prawdopodobnie z łatwością doprowadziłyby do tego, że wkrótce pojawi się kod spaghetti.

Pozwólmy sobie wyobrazić, że korzystasz z zewnętrznej biblioteki/paczki, a autor postanowił wprowadzić swój kod w inny dowolny sposób, aby poradzić sobie z niewłaściwymi stanami - zmusiłoby cię to do przystosowania się do sposobu radzenia sobie z nim - dla na przykład trzeba sprawdzić, czy określone metody zwracają wartość true lub false lub cokolwiek innego.

Korzystanie z wyjątków znacznie ułatwia obsługę błędów - po prostu zakładasz, że jeśli coś pójdzie nie tak - drugi kod rzuci wyjątek, więc po prostu owiniesz kod w bloku try i obsłużysz możliwy wyjątek na swój własny sposób.