if-return-return 또는 if-else-return을 사용하는 것이 더 효율적입니까?


141

if문 이 있다고 가정 합니다 return. 효율성 관점에서 사용해야합니까

if(A > B):
    return A+1
return A-1

또는

if(A > B):
    return A+1
else:
    return A-1

컴파일 언어 (C) 또는 스크립트 언어 (Python)를 사용할 때 서로 선호해야합니까?


11
컴파일 된 언어에서는 효율성에 대해 크게 걱정할 필요가 없습니다. 컴파일러는 그것을 분류합니다. 읽을 수 있도록 코드를 작성해야합니다. (아직 알고리즘의 효율성에 대해 걱정할 필요가 있으며 유형 등의 부실한 사용은 효율성에 영향을 미칩니다. 스타일에 대해 너무 걱정할 필요는 없습니다.) 파이썬에 대해서는 모르겠습니다.
ams

5
코드를 정렬하기 위해 컴파일러에 의존하는 것은 위험한 단계이며 오류가없는 컴파일러가 필요합니다. whay tou가 코드를 원한다는 것을 알고 있다면 더 좋습니다!
Andrew

1
당신이하고있는 것이 사양에 의해 정의된다면, 컴파일러를 의심 할 이유가 없다고 생각합니다. 그것은 당신보다 훨씬 똑똑한 사람들로 쓰여졌을 것이고, 당신이 그들보다 실수했을 가능성이 훨씬 더 높습니다.
것이다

7
의견에 근거하여 어떻게이를 폐쇄 할 수 있습니까? 둘 사이에 성능 차이가 없음을 알고 난 후 의견이있을 수 있습니다 . 나는하지 않았으며 많은 사람들이하지 않았 음을 확신합니다.
Jorge Leitao

1
질문은 매우 인기가 있지만 특정 언어를 염두에 두지 않으면 정확하게 대답 할 수 없습니다.
Emile Bergeron

답변:


195

return명령문이 현재 함수의 실행을 종료 하므로 두 형식은 동일하지만 두 번째 형식은 첫 번째 형식보다 읽기 쉽습니다.

두 형식의 효율성은 비슷하며 기본 머신 코드는 if조건이 거짓 이면 점프를 수행해야 합니다.

파이썬은 return당신의 경우에 하나의 문장 만 사용할 수있는 문법을 지원합니다 :

return A+1 if A > B else A-1

32
C도 그것을 지원합니다. return (A>B)?A+1:A-1;그러나 이와 같은 코드를 작성하면 성능전혀 향상되지 않습니다 . 우리가 달성 한 것은 코드를 난독 화하고 읽을 수 없으며 경우에 따라 암시 적 유형 프로모션에 더 취약하게 만드는 것입니다.
Lundin

47
@ 룬딘은 난독 해? 읽을 수 없습니까? 삼항 연산자를 모르는 사람에게만 해당됩니다.
glglgl

6
@Lundin이 인수에 따르면 예기치 않은 결과가 발생 <하기 때문에 나쁜 습관 -1 < 1u입니다.
glglgl

3
@glglgl : 아니요. 사람들은? : 연산자가 if-else처럼 동작하기를 기대하기 때문에 사실이 아닙니다. 누군가와 같은 코드를 작성한다면 -1 < 1u의심 할 여지없이 쉽게 버그를 발견 할 것입니다. 그러나 많은 사람들이 내가 게시 한 코드 버전을 작성합니다. 프로덕션 코드에서? : 연산자를 신뢰하기 위해 그러한 버그를 너무 자주 보았습니다. 또한 일반적으로 언어가 동일한 작업을 수행하는 두 가지 방법을 제공하는 경우 둘 중 하나만 사용하고 기분에 따라 두 가지 중 하나를 임의로 선택하지 마십시오.
Lundin

6
@Lundin은 C에서? :에주의를 기울여야 할 논쟁이지만 파이썬에도 적용된다고 말하는 것 같습니다. 파이썬에서 삼항을 사용하면 예기치 않은 결과가 발생하는 예를 지적 할 수 있습니까?
lvc

33

에서 크롬의 스타일 가이드 :

반품 후 다른 것을 사용하지 마십시오 :

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2

1
감사. +1. 반품 후 다른 것을 사용하지 않는 이유를 물어봐도 될까요?
Tim

1
if-else는 기능적으로 동일하지만 자세한 정보입니다. 다른 것은 불필요합니다.
skeller88

17
첫 번째가 더 명확하고 더 좋아 보이기 때문에 놀랐습니다.
Tim

4
어느 쪽이든 합당한 사례를 만들 수 있습니다. 이 결정에서 가장 중요한 것은 IMO가 코드베이스 내에서 일관성을 유지하는 것입니다.
skeller88

2
아마도 대부분의 경우 if-else-return브랜치가 거의 동일하지 않다는 것을 알 수 있습니다 (그렇다면 switch구성을 사용하거나 파이썬을 사용하여 dict를 열거하거나 callable 등을 사용하여 리팩토링해야 합니다). 따라서 거의 모든 if-else-return가드 절의 경우이며 else.
cowbert

5

코딩 스타일과 관련하여 :

언어에 관계없이 대부분의 코딩 표준은 단일 함수에서 여러 개의 리턴 문을 나쁜 습관으로 금지합니다.

(개인적으로는 여러 반환 문이 의미가있는 몇 가지 경우가 있다고 말하고 싶습니다 : 텍스트 / 데이터 프로토콜 파서, 광범위한 오류 처리 기능 등)

모든 업계 코딩 표준의 합의는 다음과 같이 표현을 작성해야한다는 것입니다.

int result;

if(A > B)
{
  result = A+1;
}
else
{
  result = A-1;
}
return result;

효율성과 관련하여 :

문제의 위 예와 두 가지 예는 모두 효율성 측면에서 완전히 동일 합니다. 이러한 모든 경우의 머신 코드는 A> B를 비교 한 다음 A + 1 또는 A-1 계산으로 분기 한 다음 그 결과를 CPU 레지스터 또는 스택에 저장해야합니다.

편집하다 :

출처 :

  • MISRA-C : 2004 규칙 14.7, 차례로 인용 :
  • IEC 61508-3. 3 부, 표 B.9.
  • IEC 61508-7. C.2.9.

37
단일 귀환 종교가 대부분의 코딩 표준에 영향을 미쳤습니까? 그것은 무서울 것입니다.
Daniel Fischer

7
나는 규칙이 대부분 이해가되지 않는다고 말할 것입니다. 적절한 지점에서 코드를 더 읽기 쉽고 읽기 쉽게 따르는 경향이 있습니다. 그러나 그것은 단지 나입니다. 그러나 나는 회사 / 프로젝트 별 코딩 표준을 생각했다. 나는 대부분의 단일 출구 아이디어를 사지 않기를 바랍니다.
Daniel Fischer

3
@DanielFischer : 회사를 위해 설계 한 MISRA 기반의 C 코딩 표준에서 "단일 종료 지점이 코드를 작성 하지 않는 한 , 함수는 기능 종료시 단일 종료 지점 만 갖습니다" 읽을 수없는 " 따라서 MISRA-C이지만 규칙은 예외입니다. 반환 할 수있는 고급 파서 함수를 작성하면 10 개의 다른 오류가 발생할 수 있습니다. 중괄호 수준을 사용하면 코드를 완전히 읽을 수 없습니다.이 경우 오류가 발생하면 즉시 반환하는 것이 더 합리적입니다.
Lundin

6
단일 종료점 문제에 대한 추가 토론에 대한 토론 및 추가 링크는 이 SO 질문 을 참조하십시오 . 단일 출구 지점의 규칙은 구식 지나치게 "engineeringy"되고 게다가, 파이썬은 특별히 촉진 보기 "평면 더 나은 중첩보다" , 퍼팅 return 분명히 할 일이 파이썬에서 그것을 할 수있는 관용적 인 방법입니다.
John Y

1
@percebus 나는 완전히 동의하며 순환 복잡성은 단일 반환에 대한 좋은 논쟁입니다. 그리고 나는 이것을 여러 번 MISRA위원회에 파고 들었습니다 . 예를 들어 보십시오 . 최소한이 규칙은 MISRA-C : 2012의 권고로 다운 그레이드되었습니다.
Lundin

3

합리적인 컴파일러라면 차이가 없어야합니다. 그것들은 동등한 머신 코드로 컴파일되어야합니다.


2

통역사가 신경 쓰지 않기 때문에 이것은 스타일 (또는 선호도)의 문제입니다. 개인적으로 함수 기반 이외의 들여 쓰기 수준에서 값을 반환하는 함수의 최종 진술을 만들려고하지 않습니다. 예제 1의 else는 함수의 끝이 약간만있는 경우 모호합니다.

선호에 따라 다음을 사용합니다.

return A+1 if (A > B) else A-1

함수에서 마지막 명령문으로 단일 리턴 명령문을 갖는 좋은 규칙 (이미 언급 한 바와 같이)과 필수 스타일 중간 결과를 피하는 좋은 기능적 프로그래밍 패러다임 모두를 준수합니다.

더 복잡한 함수의 경우 가능한 경우 조기 리턴을 피하기 위해 함수를 여러 하위 함수로 나누는 것을 선호합니다. 그렇지 않으면 rval이라는 명령형 스타일 변수를 사용하여 되돌립니다. 함수가 사소하거나 끝 전에 return 문이 오류의 결과가 아닌 한 여러 return 문을 사용하지 마십시오. 일찍 돌아 오면 계속할 수 없다는 사실이 강조됩니다. 여러 하위 함수로 분기되도록 설계된 복잡한 함수의 경우 함수를 사례 문으로 코딩하려고합니다 (예를 들어 dict에 의해 구동 됨).

일부 포스터는 작동 속도를 언급했습니다. 실행 속도가 필요한 경우 Python이 사용하기 가장 좋은 언어가 아니기 때문에 런타임 속도는 나에게 부차적입니다. 나는 파이썬을 나에게 중요한 코딩 효율 (즉 오류없는 코드 작성)로 사용한다.


1
사용자가 내 답변을 다운 투표 할 경우 왜 내가 틀렸다고 생각하는지에 대한 의견을 보내 주셔서 감사합니다.
Stephen Ellwood 2012

가독성을 높이기 위해 한 줄에 한 줄을 작성하기 전에 한 줄을 작성했을 것입니다. var n = 1 if (A > B) else -1 return A+n
percebus

어떤 경우에는 @percebus 변수 이름이 의미를 향상시킬 수 있는지에 동의합니다. 예 : 'code'move_x = 1 if my_x <상대 _x else -1 # 상대쪽으로 이동
Stephen Ellwood

BTW 실제로 귀하의 답변을 상향 조정했습니다. 내 대답이 다소 비슷하다는 것을
알면

2

else가능한 경우 개인적으로 블록을 피 합니다. 참고 항목 안티 경우 캠페인

또한 그들은 회선에 대해 '추가'를 청구하지 않습니다.

"단순한 것이 복잡한 것보다 낫다" & "가독성은 왕이다"

delta = 1 if (A > B) else -1
return A + delta

2
왜 다운 투표? 'pythonic'답변입니다. 선호하는 답변으로 간주하지 않을 수 있습니다. 그러나 잘못된 것은 아닙니다. 나는 또한 KISS 원칙을
따르고있다

3
나는 가독성과 단순성으로 점수를 매기 때문에 귀하의 답변을 찬성했습니다. 나는 개인적으로 내 대답이 적극적으로 부정적인 이유에 대해 교육하지 않고 누군가가 저에게 투표하지 않는다는 것을 개인적으로 알았습니다.
Stephen Ellwood

1
Anti-if 캠페인에 대해 들어 본 적이 없지만 if가 위험한 이유를 이해할 수 있습니다. 나는 항상 if 문으로 묶인 코드의 양을 제한하고 dict를 사용하기 위해 elif 트리를 다시 작성하려고합니다. 그래도 주제가 조금 벗어납니다.
Stephen Ellwood

1
@StephenEllwood dictdiff를 피하기 위해 s를 사용 하는 것은 성능 측면에서 매우 나쁜 생각입니다.
Bachsau

@Bachsau 아마 옳을 것입니다. 모든 스크립트가 몇 초 만에 실행되므로 성능에 대해 걱정할 필요가 없었습니다. 나를 위해 가독성은 일반적으로 성능을 능가합니다. 전임 프로그래머가 아니기 때문에; 그것들은 단지 목적을위한 수단 일뿐입니다.
Stephen Ellwood

1

버전 A가 더 간단하므로 사용하려고합니다.

그리고 Java에서 모든 컴파일러 경고를 켜면 두 번째 버전이 불필요하고 코드 복잡성이 높아져 두 번째 버전에 경고가 표시됩니다.


1

나는 질문에 파이썬 태그가 붙어 있다는 것을 알고 있지만 동적 언어를 언급하므로 루비에서는 if 문에 실제로 반환 유형이 있으므로 다음과 같은 작업을 수행 할 수 있다고 언급해야한다고 생각했습니다

def foo
  rv = if (A > B)
         A+1
       else
         A-1
       end
  return rv 
end

또는 단순히 암시 적 반환도 있기 때문에

def foo 
  if (A>B)
    A+1
  else 
    A-1
  end
end

여러 리턴이없는 스타일 문제를 해결합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.