2012-06-11 2 views
1

나는 아래의 자바 조각이 problem 해결하려고하고있다 : 누구의 수락 제출 단지에 대해 비용을 다른 많은 사용자가있는 동안 내 프로그램을 판단 할 때Java 코드의 성능을 향상 시키려면 어떻게해야합니까?

Scanner scanner = new Scanner(System.in); 
    int testNum = scanner.nextInt(); 
    StringBuilder sb = new StringBuilder(); 
    double x; 
    double y; 
    int year; 
    for(int i = 0; i < testNum; i++) { 
     x = scanner.nextDouble(); 
     y = scanner.nextDouble(); 
     year = (int)((x * x + y * y) * Math.PI/100); 
     sb.append("Property ").append(i+1).append(": This property will begin eroding in year "); 
     if(year * 100/Math.PI < x * x + y * y) 
      sb.append(year+1); 
     else 
      sb.append(year); 
     System.out.println(sb.append('.')); 
     sb.delete(0, sb.length()); 
    } 
    System.out.println("END OF OUTPUT."); 

, 나는 그것을 발견은 3164K 메모리와 125ms의 시간 비용 92K 메모리 및 15MS 시간. 그것은 내 결과보다 훨씬 낫습니다. 그래서이 문제를 해결할 더 좋은 방법이 있습니까?

+0

저는 루프가 프로세서에서 가장 힘들다고 생각합니다. 그것이 무엇이든 할 지 모르겠지만 아마 while 루프로 만들 수 있을까요? 'while (scanner.hasNext())'아마도? –

+0

나는 그들이 당신의 시간 가치가없는 일종의 IO 최적화를한다고 생각한다. 스캐너를 사용하지 않고 BufferReader + StringTokenizer + Double.parseDouble()을 사용해보십시오. 당신은 또한 char [] 로의 입력을 읽고 자신을 파싱하고 char []에서 작업하여 정수를 출력함으로써 조금 더 낮은 레벨로 시도 할 수도 있습니다. 그러나 이런 종류의 최적화를하는 데 소비하는 시간이 경쟁력있는 프로그래밍에 도움이되지 않는다고 보장합니다. – nhahtdh

+1

if 문이'(x * x + y * y)> (x * x + y * y)'를 검사하는 것으로 보입니다. 그것을 제거 하시겠습니까? 또한 StringBuilder를 추가하고 계속 지우거나 반복 할 때마다 String 값을 재 할당하는 것이 더 빠릅니까? – acattle

답변

2

이 코드는 거의 확실하게 입력 바인딩, 프로세서가 아닌 바인딩 될 것이다, 그래서 모든 코드 '최적화'를 시도에는 포인트는 아마 존재하지 않는다. 키보드에서 입력을 읽는다면 입력 할 수있는만큼 빠르게 실행되기 때문에 입력 지점이 더 적습니다. System.in이 리디렉션 된 경우 마이크로 최적화를 수행하려면 StringBuilder, 대신 Formatter을 사용하고 두 번째가 아닌 PI 표현식을 한 번만 계산할 것입니다.하지만 JVM이이를 발견 할 수 있습니다.

+0

이것은 온라인 판사이므로 입력이 명확하게 리디렉션됩니다. 그리고 스캐너는 내부적으로 패턴을 사용하기 때문에 입력 속도가 느려지는 것을 확인합니다. – nhahtdh

+0

@nhahtdh 입력이 느린 이유는 주로 BufferedInputStream이 수정하는 한 번에 한 바이트이기 때문입니다. Pattern이 수정되지 않아서가 아닙니다. – EJP

+0

사실 일 수 있습니다. 몇 가지 구현 (예 : BufferedReader + StringTokenizer)으로 테스트했지만 버퍼 된 스캐너와 버퍼되지 않은 스캐너를 비교하지 않았습니다. – nhahtdh

0

StringBuilder를 사용하여 문자열을 작성한 다음 즉시 인쇄하고 StringBuilder가 여분의 처리를 수행하고 if 문을 검사하여 if 또는 it를 반올림해야하는지 결정하는 것으로 보입니다. 또한 루프를 통해 매회 Math.PI * 100의 값을 다시 계산합니다. 당신은 같은 것을 시도 할 수 :

Scanner scanner = new Scanner(System.in); 
int testNum = scanner.nextInt(); 

double x; 
double y; 
double factor = Math.PI * 100; 

for(int i = 0; i < testNum; i++) { 
    x = scanner.nextDouble(); 
    y = scanner.nextDouble(); 

    System.out.println("Property " + (i+1) + ": This property will begin eroding in year " + Math.round((x * x + y * y) * factor) + "."); 
} 
System.out.println("END OF OUTPUT."); 
관련 문제