"B"인쇄가 "#"인쇄보다 현저하게 느린 이유는 무엇입니까?


2746

1000x의 두 행렬을 생성했습니다 1000.

첫 번째 행렬 : O및 #.
두 번째 매트릭스 : O및 B.

다음 코드를 사용하여 첫 번째 행렬을 완료하는 데 8.52 초가 걸렸습니다.

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("#");
        }
    }

   System.out.println("");
 }

이 코드를 사용하여 두 번째 행렬을 완료하는 데 259.152 초가 걸렸습니다.

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B"); //only line changed
        }
    }

    System.out.println("");
}

실행 시간이 크게 다른 이유는 무엇입니까?


주석에서 제안한 것처럼 인쇄하는 System.out.print("#");데 7.8871몇 초 밖에 걸리지 않지만을 System.out.print("B");제공합니다 still printing....

정상적으로 작동한다고 지적한 다른 사람들과 같이, 나는 예를 들어 Ideone.com 을 시도 했으며 두 코드 조각 모두 동일한 속도로 실행됩니다.

시험 조건:

  • Netbeans 7.2 에서이 테스트를 콘솔로 출력하여 실행했습니다.
  • 나는 System.nanoTime()측정에 사용

62
랜덤 생성기의 영향을 제거하려면 rand.nextInt (4) == 0을 i <250으로 변경하십시오. 엔트로피가 부족하여 임의 생성 속도가 느려질 수 있습니다.
— fejese

3
둘 다 내 컴퓨터에서 ~ 4 초 동안 같은 시간 동안 실행되는 것 같습니다.
— Sotirios Delimanolis 2013

155
B를 인쇄하는 것이 # 인쇄하는 것보다 더 많은 시간이 걸린다는 것을 제안한다면 .... 왜 임의의 변수 r에 의존하기보다는 모든 B와 모든 #을 인쇄하려고하지
— 않습니까?

18
허용 된 답변을 바탕으로 파일 또는 / dev / null로 리디렉션 된 출력으로 실행하려고 시도하지 않은 것 같습니다.
— Barmar

24
@fejese, Random ()은 암호화 RNG가 아니므로 엔트로피 풀을 사용하지 않습니다.
— 나누기

답변:


4070

순수한 추측 은 문자 줄 바꿈 대신 단어 줄 바꿈 을 시도 B하고 단어 문자로하지만 #비 단어 문자로 취급 하는 터미널을 사용하고 있다는 것 입니다. 따라서 줄의 끝에 도달하여 줄을 끊을 곳을 찾으면 #거의 즉시 보고 행복하게 끊습니다. 반면에는 B더 오래 검색해야하며 줄 바꿈 할 텍스트가 더 많이있을 수 있습니다 (일부 터미널에서는 백 스페이스를 출력 한 다음 공백을 출력하여 줄 바꿈 된 문자를 덮어 쓰기).

그러나 그것은 순수한 추측입니다.


559
이것은 실제로 정답입니다! B해결 후 공백을 추가 하십시오.
— Kuba Spatny

261
어려운 경험에서 비롯된 몇 가지 답변이 있습니다. TJ와 나는 (우리가 친구이기 때문에) 애플과 zx80 / ​​81 시대에 자랐습니다. 당시에는 자동 줄 바꿈이 없었습니다. 그래서 우리는 두 번 이상 자신의 글을 썼습니다. 그리고 그 교훈은 당신과 함께, 그들은 당신의 도마뱀 뇌에 태워집니다. 그러나 그 후에 코드에 의존하면 환경 단어가 모든 것을 줄 바꿈하거나 런타임 전에 수동으로 수행하면 단어 줄 바꿈 문제가 발생하기가 더 어렵습니다.
— JockM

315
화려한 공제. 그러나이 강의를 일반화하고 항상 출력을 제거하거나 / dev / null (Windows의 NUL) 또는 최소한 파일로 출력하여 성능을 측정해야합니다. 모든 종류의 콘솔에 표시하는 것은 일반적으로 비용이 많이 드는 IO이며, 그렇게 혼란스럽지 않더라도 항상 타이밍을 왜곡합니다.
— Bob Kerns

37
@MrLister : 워드 랩핑을 System.out.println하지 않습니다. 그것이 출력하는 것은 단어 줄 바꿈을하고 System.out.println있었습니다 (그리고 차단했기 때문에 기다려야했습니다).
— TJ Crowder 2019

35
@Chris-사실, 그것들을 인쇄하지 않으면 알고리즘의 정확한 타이밍을 얻는 문제에 대한 해결책이라고 주장합니다. 콘솔로 인쇄 할 때마다 성능 테스트와 관련이없는 모든 외부 처리 방식을 호출합니다. 그것은 순수하고 간단한 측정 과정의 버그입니다. 반면에 문제를 측정으로 보지 않고 불일치를 이해하면 인쇄하지 않는 것이 디버깅 트릭입니다. 어떤 문제를 해결하려고합니까?
— Bob Kerns

209

Java 버전 1.8을 사용하여 Eclipse vs Netbeans 8.0.2에서 테스트를 수행했습니다. System.nanoTime()측정에 사용 했습니다.

식:

나는 두 경우 모두 약 1.564 초 에 같은 시간을 가졌다 .

넷빈즈 :

  • "#"사용 : 1.536 초
  • "B"사용 : 44.164 초

따라서 Netbeans의 콘솔에서 인쇄시 성능이 좋지 않은 것 같습니다.

더 많은 연구를 한 결과 문제는 Netbeans의 최대 버퍼 ( 명령에 국한되지 않음)의 줄 바꿈이라는 것 입니다 System.out.println.

for (int i = 0; i < 1000; i++) {
    long t1 = System.nanoTime();
    System.out.print("BBB......BBB"); \\<-contain 1000 "B"
    long t2 = System.nanoTime();
    System.out.println(t2-t1);
    System.out.println("");
}

시간 결과가 약 225 밀리 초인 경우 시간 결과는 매 5 회 반복을 제외한 모든 반복마다 1 밀리 초 미만 입니다. (나노초 단위)

BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
BBB...31744
BBB...31744
BBB...31744
BBB...31744
BBB...226365807
.
.
.

등등..

요약:

  1. Eclipse는 "B"와 완벽하게 작동
  2. Netbeans에는 줄 바꿈 문제가 있습니다 (이클립스에서는 문제가 발생하지 않기 때문에) (B 다음에 공백을 추가하지 않고 ( "B")) 해결할 수 있습니다.

32
연구 전략에 대해 자세히 설명하고 마침내 줄 바꿈이 범인이라는 것을 알게 된 계기는 무엇입니까? (나는 당신의 탐정 기술이 궁금합니다!)
— silph

12

그렇습니다. 범인은 확실히 줄 바꿈입니다. 두 프로그램을 테스트했을 때 NetBeans IDE 8.2는 다음과 같은 결과를 얻었습니다.

  1. 첫 번째 행렬 : O 및 # = 6.03 초
  2. 두 번째 매트릭스 : O와 B = 50.97 초

코드를 자세히 보면 첫 번째 루프 끝에서 줄 바꿈을 사용했습니다. 그러나 두 번째 루프에서는 줄 바꿈을 사용하지 않았습니다. 따라서 두 번째 루프에서 1000 자로 단어를 인쇄합니다. 단어 줄 바꿈 문제가 발생합니다. B 뒤에 단어가 아닌 문자 "" 를 사용하면 프로그램을 컴파일하는 데 5.35 초 밖에 걸리지 않습니다 . 100 개의 값 또는 50 개의 값을 전달한 후 두 번째 루프에서 줄 바꿈을 사용하면 각각 8.56 초 와 7.05 초만 걸립니다 .

Random r = new Random();
for (int i = 0; i < 1000; i++) {
    for (int j = 0; j < 1000; j++) {
        if(r.nextInt(4) == 0) {
            System.out.print("O");
        } else {
            System.out.print("B");
        }
        if(j%100==0){               //Adding a line break in second loop      
            System.out.println();
        }                    
    }
    System.out.println("");                
}

또 다른 조언은 NetBeans IDE의 설정을 변경하는 것입니다. 우선 NetBeans 도구 로 이동하여 옵션을 클릭하십시오 . 그런 다음 편집기 를 클릭 하고 서식 탭으로 이동 하십시오. 그런 다음 Line Wrap Option 에서 Anywhere 를 선택하십시오 . 프로그램을 컴파일하는 데 거의 6.24 %의 시간이 걸립니다.

NetBeans 편집기 설정

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