Załóżmy, że mam if
oświadczenie z rozszerzeniem return
. Z punktu widzenia wydajności powinienem użyć
if(A > B):
return A+1
return A-1
lub
if(A > B):
return A+1
else:
return A-1
Czy powinienem preferować jeden czy inny język, używając języka skompilowanego (C) czy języka skryptowego (Python)?
python
c
performance
compiler-construction
Jorge Leitao
źródło
źródło
Odpowiedzi:
Ponieważ
return
instrukcja kończy wykonywanie bieżącej funkcji, obie formy są równoważne (chociaż druga jest prawdopodobnie bardziej czytelna niż pierwsza).Wydajność obu form jest porównywalna, podstawowy kod maszynowy musi wykonać skok, jeśli
if
warunek i tak jest fałszywy.Zwróć uwagę, że Python obsługuje składnię, która pozwala na użycie tylko jednej
return
instrukcji w twoim przypadku:źródło
return (A>B)?A+1:A-1;
Jednak pisanie takiego kodu nie przynosi absolutnie żadnych korzyści . Wszystko, co osiągnęliśmy, to uczynić kod zaciemnionym, nieczytelnym, aw niektórych przypadkach bardziej podatnym na niejawne promocje typu.<
jest złą praktyką, ponieważ-1 < 1u
daje nieoczekiwany wynik.-1 < 1u
, w co wątpię, z łatwością wykryłby błąd. Sporo ludzi napisałoby jednak jakąś wersję kodu, który opublikowałem. Widziałem takie błędy zbyt często w kodzie produkcyjnym, aby zaufać operatorowi?:. Z zasady, jeśli język daje ci dwa różne sposoby zrobienia tego samego, użyj tylko jednego z nich, nie wybieraj losowo żadnego z nich w zależności od nastroju.Z przewodnika stylistycznego Chromium :
Nie używaj innego po zwrocie:
źródło
if-else-return
gałęzie prawie nigdy nie są równe (jeśli tak, to i tak powinieneś refaktoryzować; albo używającswitch
konstrukcji, albo dla Pythona, wyliczając dyktafon / używając wywoływalnego / itp.). Dlatego prawie wszystkieif-else-return
są przypadkami klauzul ochronnych i te są zawsze testowalne (kpią z testowanego wyrażenia) bez rozszerzeniaelse
.Odnośnie stylu kodowania:
Większość standardów kodowania bez względu na język zakazuje wielu instrukcji powrotu z jednej funkcji jako zła praktyka.
(Chociaż osobiście powiedziałbym, że istnieje kilka przypadków, w których wiele instrukcji powrotu ma sens: parsery protokołu tekstu / danych, funkcje z rozbudowaną obsługą błędów itp.)
Konsensus wszystkich tych branżowych standardów kodowania jest taki, że wyrażenie powinno być zapisane jako:
Jeśli chodzi o wydajność:
Powyższy przykład i dwa przykłady w pytaniu są całkowicie równoważne pod względem wydajności. We wszystkich tych przypadkach kod maszynowy musi porównać A> B, następnie rozgałęzić się do obliczenia A + 1 lub A-1, a następnie zapisać wynik w rejestrze procesora lub na stosie.
EDYTOWAĆ :
Źródła:
źródło
return
tam , gdzie jest to jasne, jest idiomatycznym sposobem na zrobienie tego w Pythonie.Z każdym rozsądnym kompilatorem nie powinno się zauważać żadnej różnicy; powinny być skompilowane do identycznego kodu maszynowego, ponieważ są równoważne.
źródło
Jest to kwestia stylu (lub preferencji), ponieważ tłumaczowi to nie przeszkadza. Osobiście postarałbym się nie robić ostatniej instrukcji funkcji, która zwraca wartość na poziomie wcięcia innym niż podstawa funkcji. Inne w przykładzie 1 przesłania, choćby nieznacznie, gdzie znajduje się koniec funkcji.
Preferuję:
Ponieważ jest zgodny zarówno z dobrą konwencją posiadania pojedynczej instrukcji return jako ostatniej instrukcji w funkcji (jak już wspomniano), jak i dobrym paradygmatem programowania funkcjonalnego polegającym na unikaniu pośrednich wyników w stylu imperatywnym.
W przypadku bardziej złożonych funkcji wolę podzielić funkcję na wiele podfunkcji, aby uniknąć przedwczesnych zwrotów, jeśli to możliwe. W przeciwnym razie wracam do używania imperatywnej zmiennej stylu o nazwie rval. Staram się nie używać wielu instrukcji return, chyba że funkcja jest trywialna lub instrukcja return przed końcem jest wynikiem błędu. Przedwczesny powrót podkreśla fakt, że nie możesz iść dalej. W przypadku złożonych funkcji, które są zaprojektowane do rozgałęziania się na wiele podfunkcji, próbuję je zakodować jako instrukcje case (na przykład sterowane dyktowaniem).
Niektóre plakaty wspominały o szybkości działania. Szybkość działania jest dla mnie drugorzędna, ponieważ jeśli potrzebujesz szybkości wykonywania, Python nie jest najlepszym językiem do użycia. Używam Pythona, ponieważ jego efektywność kodowania (tj. Pisania kodu wolnego od błędów) jest dla mnie ważna.
źródło
var n = 1 if (A > B) else -1
return A+n
Osobiście unikam
else
blokad, jeśli to możliwe. Zobacz kampanię Anti-ifPoza tym nie pobierają „dodatkowej” opłaty za linię, wiesz: str
„Proste jest lepsze niż złożone” i „Czytelność jest najważniejsza”
źródło
dict
s do unikania różnic jest bardzo złym pomysłem pod względem wydajności.Wersja A jest prostsza i dlatego bym jej użył.
A jeśli włączysz wszystkie ostrzeżenia kompilatora w Javie, otrzymasz ostrzeżenie o drugiej wersji, ponieważ jest to niepotrzebne i powoduje złożoność kodu.
źródło
Wiem, że pytanie jest otagowane jako python, ale wspomina o językach dynamicznych, więc pomyślałem, że powinienem wspomnieć, że w języku ruby instrukcja if faktycznie ma typ zwracany, więc możesz zrobić coś takiego
Lub dlatego, że ma również niejawny zwrot po prostu
co całkiem dobrze rozwiązuje problem stylu polegający na tym, że nie ma wielu zwrotów.
źródło