2011-01-29 5 views
1

내 코드를보고있는 동안 많은 질문이 나타났습니다. 사람들이 코드 조각에 대해 어떻게 생각하는지 알고 싶습니다. 각각 하나씩, 나는 더 최적화 된 것이 무엇인지, 그리고 더 나은 연습이나 더 깨끗한 것이 무엇인지 궁금합니다. 대부분의 경우 가능한 모든 최적화는 나노초 단위로 이루어 지므로 이론적으로는 궁금합니다. :)Java 최적화 질문

1) 첫 번째 오류는 오류를보고해야하는 자주 호출되는 루틴입니다. 이

if(success) 
//Stuff 
else 
reportInternalError(); 

어떤 혜택 만 그런 일이 처음 오류를보고 할 예정이다) (

if(success) { 
//Stuff 
return; 
} 
reportInternalError(); 

2) reportInternalError로 변경하는 것처럼 지금은보고, 잠재적으로 할 수있다 매우 자주 불렀다. 현재, 내가 마지막 하나에 대한 코드를 중복)

if(reported) 
return; 
//Report error 
reported = true; 

3로 변경에 대해 생각하고이

if(!reported) { 
//Report error 
reported = true; 
} 

같다. 나는 똑같은 코드를 두 번 사용하고 있으며 더 좋은 방법을 쓰려고 노력하고있다.

try { 
//Stuff 
} catch(){ 
} 

while(loop) { 
try { 
    //Same Stuff 
} catch(){ 
    loop = false; 
} 
} 

first = true; 
do { 
try { 
    //Stuff 
} catch() { 
    if(!first) 
     loop = false; 
} 
first = false; 
} while(loop); 

대 감사합니다!

+1

이 올바른 런타임 성능 차이는 아무도 알 수 없을 것이다 그래서 믿을 수 없을만큼 negible 될 것입니다.) 심지어는 이론적으로는 시간 낭비라고 생각하면 안됩니다. – delnan

답변

2

나는 마이크로 최적화를 통해 가독성과 유지 보수에 프리미엄을 둘 것 : 나는 다음과 같이 작성합니다 # 3에 대해서는

. 마이크로 최적화의 이득은 실제로는 부주의합니다 (오늘날의 컴파일러, JIT 및 프로세서의 정교함을 감안할 때 종종 부적합합니다).

나의 선택은 :

1) 나는 가지의 주요 코드 경로와 예외 경우에 따라서 일반적인 경우를 넣어보십시오

if (! success) { 
    reportInternalError(); 
} 

// Stuff 

2) 내가 원래의 접근 방식을 선호한다. 다른 방법은 메소드가 항상 return을 원할 것이라고 가정하지만, 앞으로 더 많은 것을 할 필요가 있다면 어떻게해야할까요? 나는 그 여분의 물건 분기에 가고 싶지 않아 :

if (! reported) { 
    // Report error 
    reported = true; 
} 
// extra stuff to do 

3) 리팩토링 버전은 나에게 더 유지 보수 보인다. 나는 간단한 breaktargetExceptionWasThrown 교체에 대한 울타리에있어 : ​​

boolean isFirstIteraton = true; 
boolean targetExceptionWasThrown = false; 
do { 
    try { 
     //Stuff 
    } catch() { 
     if (! isFirstIteraton) { 
      targetExceptionWasThrown = true; 
     } 
    } 
    isFirstIteraton = false; 
} while (! targetExceptionWasThrown); 
+0

감사합니다. 귀하는 귀하의 선택에 대해 많은 정당성을 부여했습니다. –

+1

@ 케빈 S - 고마워. 나는 이유가 중요하다고 생각하기 때문에 : (1) 나는 논리가 잘못되어 누군가가 나를 바로 잡을 수 있기를 원합니다. (2) 모든 경우를 다루는 일을하는 절대적인 올바른 방법은 하나도 없습니다. 언제 벗어날지를 알기위한 근거를 알아야합니다. –

4

걱정하지 마십시오. 오늘날의 컴퓨터 파워는 뇌의 힘보다 훨씬 저렴하므로 가독성을 위해 코드를 최적화하십시오. 어쩌면 몇 마이크로 초가 걸릴 수도 있습니다.

게다가 JVM의 JIT 컴파일러가 이러한 최적화를 가장 잘 수행합니다. 그렇지 않은 경우에도 성능이 향상되는 것처럼 수정되어 프로그램이 느려질 수 있습니다. Josh Bloch는 작년 Devoxx에서이 주제에 대해 훌륭한 presentation을주었습니다.

+3

제 프로그래밍 선생님 중 한 명이이 문제에 관해 좋은 말을 전했습니다. "컴파일러보다 현명하지 않으려 고 노력하십시오" – esaj

2

# 3과 관련하여 예외가 루프에서 빠져 나오면 try-catch을 루프 외부에 넣으십시오.

try { 
//Stuff 
} catch(){ 
} 

try { 
    while(true) { 
    //Same Stuff 
    } 
} catch(){ 
} 

하지만 당신은 (대신 loop VAR의) 더 좋을 수도 두 번째 예에서는 break을 사용하는 중복의 일부 금액을 가지고 있기 때문이다.

first = true; 
while (true) { 
try { 
    //Stuff 
} catch() { 
    if(!first) 
     break; 
} 
first = false; 
}; 

그렇지 않은 경우 //Stuff에 대해 별도의 방법을 만들 수 있습니다. 첫 번째 예제의 명확성은 보존되지만 중복은 제거됩니다.

1

매우 낮은 수준 (즉, 어셈블리 언어의 특수 마이크로 프로세서)의 코드를 작성하지 않는 한 이러한 개선 사항은 성능에 미치는 영향이 미미합니다. 나는 가독성이 높은 수준에서 더욱 중요하다는 것에 동의한다.

+0

조언을 주셔서 감사합니다. 이것은 제가 이미 알고 있고 OP에서 언급 한 것입니다. 나는 정말로 구체적인 답을 찾고 있었다. –

1

이론적으로나 실제적으로 컴파일러는 이러한 종류의 마이크로 최적화를 처리해야합니다. 대신 명확성에 초점을 맞추고 단일 반환 관용구를 고수하십시오 : 모든 함수/메소드의 끝에는 return 문이 하나 있어야합니다.

세 번째 예에서 사용자의 의도는 적어도 try/catch 블록을 두 번 실행하는 것입니다. 시도해보십시오.

for (int i=0; i<2 || loop; i++) { 
    // put the try/catch block here 
} 
1

성능 향상을 위해 능숙하지 못하게하고 대신 가독성에 중점을 두어서는 안되는 다른 대답에 동의합니다. 무엇 내가 사건이있을 때 내가 사용하는 것은 1과 2는 이것이다 :

경우 1 :

if(! success) { 
    reportInternalError(); 
    return; 
} 

// do Stuff 

및 사례 2

:

if(reported) 
return; 

//Report error 
reported = true; 

는 기본적으로 가드 조항 패턴입니다. http://www.c2.com/cgi/wiki?GuardClause. 이는 코드를 실행하기 전에 일부 불변식이 충족되는지 확인하려는 경우에 올바르게 작동합니다. 이 경우 다중 반품 규칙을 위반하는 것이 좋습니다. 또한 코드를 실행하기 전에 어떤 조건을 충족해야하는지 한눈에 확인할 수 있으므로 코드를 더 쉽게 읽을 수 있습니다.

try { 

     boolean finished = false; 
     do { 

      //Same Stuff 

      if (/* end of loop test */) { 
       finished = true; 
      } 
     } while (! finished); 
    } catch() { 
     // handle exception  
    }