「B」の印刷が「#」の印刷よりも劇的に遅いのはなぜですか?


2748

1000xの2つの行列を生成しました1000

最初のマトリックス:O#
2番目のマトリックス: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("");
 }

このコードを使用すると、2番目のマトリックスが完了するまでに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 14

155
Bの印刷に#....を印刷するよりも時間がかかることを示唆している場合、ランダム変数rに依存するのではなく、すべてのBとすべての#を印刷しようとしないのはなぜ
ですか

18
受け入れられた回答に基づいて、出力をファイルまたは/ dev / nullにリダイレクトして実行しようとはしていないようです。
Barmar 2014

24
@ fejese、Random()は暗号化されたrngではないため、エントロピープールを使い果たしません。
2014

回答:


4072

純粋な推測は、文字の折り返しではなく単語の折り返しを行おうとする端末を使用していBて、単語文字としてではなく単語以外の文字として扱う#というものです。そのため、行の終わりに達して行を#分割する場所を検索すると、ほとんどすぐに幸せな場所で改行します。一方、を使用するとB、より長い時間検索し続ける必要があり、折り返すテキストが多くなる可能性があります(一部の端末では、バックスペースを出力してからスペースを出力して折り返される文字を上書きするなど、コストがかかる場合があります)。

しかし、それは純粋な推測です。


560
これが正解です。B解決後にスペースを追加します。
Kuba Spatny 2014

261
一生懸命学んだ経験から得られるいくつかの答えがあります。TJと私は(私たちは友達なので)Apple] [とzx80 /​​ 81の時代に育ちました。当時、組み込みのワードラップはありませんでした。ですから、私たち2人は結局自分自身で作成することになりました—複数回 そして、それらのレッスンはあなたに固執し、トカゲの脳に焼き付きます。しかし、その後コードに頼った場合、環境の単語がすべてをラップするか、実行前に手動で行うと、ワードラップの問題に遭遇するのが難しくなります。
JockM 2014

315
華麗な控除。ただし、このレッスンから一般化し、常に、/ dev / null(WindowsのNUL)または少なくともファイルに出力を削除してパフォーマンスを測定する必要があります。あらゆる種類のコンソールでの表示は、一般的に非常に負荷の高いIOであり、これほど劇的に混乱するわけではありませんが、常にタイミングをゆがめます。
Bob Kerns、2014

37
@MrLister:ワードラップを行いSystem.out.printlnません。それが出力していたのは、ワードラップ(そしてブロッキングなのでSystem.out.println、待たなければなりませんでした)でした。
TJクラウダー

35
@Chris-実際には、それらを印刷しないことが、アルゴリズムの正確なタイミングを取得する問題の解決策であると主張します。(何らかの種類の)コンソールに出力するたびに、パフォーマンスのテスト対象とは関係のないあらゆる種類の外部処理を呼び出します。これは、純粋で単純な測定手順のバグです。一方、問題を測定としてではなく、不一致を理解している場合、はい、印刷しないことはデバッグのトリックです。結局のところ、どの問題を解決しようとしていますか?
Bob Kerns 2014

210

私はEclipseとNetbeans 8.0.2のテストを両方ともJavaバージョン1.8で行いました。System.nanoTime()測定に使用しました。

日食:

私は両方のケースで同じ時間を得ました-およそ1.564秒

Netbeans:

  • 「#」の使用: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には解決できる行折り返しの問題があります(この問題はEclipseでは発生しないため)(Bの後にスペースを追加することなく( "B"))。

32
研究戦略について詳しく説明してから、最終的に何が原因で、行の折り返しが原因であると判明したのでしょうか。(私はあなたの探偵スキルに興味があります、つまり!)
シルフ

12

はい、犯人は間違いなく折り返しです。私があなたの2つのプログラムをテストしたとき、NetBeans IDE 8.2は私に次の結果を与えました。

  1. 最初のマトリックス:Oおよび#= 6.03秒
  2. 2番目のマトリックス:OおよびB = 50.97秒

コードを注意深く見ると、最初のループの終わりに改行が使用されています。しかし、2番目のループでは改行を使用しませんでした。したがって、2番目のループで1000文字の単語を印刷します。これにより、折り返しの問題が発生します。Bの後に単語以外の文字 ""を使用すると、プログラムのコンパイルに5.35秒しかかかりません。また、100個の値または50個の値を渡した後、2番目のループで改行を使用すると、それぞれ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("");                
}

もう1つのアドバイスは、NetBeans IDEの設定を変更することです。まず、NetBeans ツールに移動し、[ オプション ]をクリックします。その後、「エディター」をクリックして、「フォーマット」タブに移動します。そして、選択どこ行ラップのオプション。プログラムのコンパイルにかかる時間が6.24%近く短縮されます。

NetBeansエディタの設定

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.