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


2746

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

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

다음 코드를 사용하여 첫 번째 행렬을 완료하는 데 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.