2012-02-17 17 views
3

アプレット検索ユーティリティを作成しました。このユーティリティでは、入力として文字列を指定し、その文字列を指定したファイルまたはフォルダで検索します。
私はこれでやったが、私はその性能に満足していない。
処理に時間がかかり過ぎています。
何が起きているかを見るためにプロファイリングをすることにしました。scanner.hasNextLine()メソッドがほとんどの時間を費やしていることに気付きました。
私はすべての行を読み込み、その文字列を検索する必要があるため、これは私のプログラムのために非常に重要な方法ですが、私はその性能を向上させ、実行時間ここ
Javaプログラムのパフォーマンスを向上させる

を削減することが可能な他の方法は、コードがあるです私はこのメソッドを使用しています。

そして、はいtoLowerCase()メソッドは、さらに時間がかかると予想しています。


私は自分のコードを変更したとアレックスとNRJが提案し、私は自分のアプリケーションのパフォーマンスでの素敵な改善を見つけとして今私はScannerの代わりにBufferedReaderを使用しています。
これは、以前のバージョンの1/3に処理されています。
お返事いただきありがとうございました.....

+0

地球上では、Webページ内のファイルのファインダーを埋め込んでいるのはなぜ? –

+0

あなたのコメントはありがたいですが、アプレットはデスクトップアプリケーションであるWebページに埋め込まれていません。 –

+0

「アプレット」とは、a)「小さなアプリケーション」、またはb)「アプレット」または「JApplet」を拡張するクラスを意味しますか? –

答えて

3

:私はこのようなものを使用してJavaからのgrepを呼び出します。大規模なデータを処理するのに最適化されていません。あなたがしようとするために、これが十分でない場合

r.readLine()

BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))

はその後、ライン・バイ・ラインを読む:私は FileInputStreamラップ InputStreamReaderラップシンプル BufferedReader使用することをお勧めいたしますたいです大量の行を読み込んで処理します。

toLowerCase()については、代わりに正規表現を使用できます。利点は、たびに行の大文字と小文字を変更する必要がないことです。欠点は単純なケースでは、正規表現が通常の文字列比較より少し遅いことです。

+0

ありがとうございましたAlex私はBufferedReaderを試してみて、それがうまくいくなら私はここですべての視聴者に確実に通知します。 –

-2

文字列の一致をファイルシステムで検索するのにJavaを使用しません。代わりにJavaからネイティブアルゴリズムを呼び出す。私はScannerのコードを調べて、私はあなたが正しいと思い、あなたの質問に続いて

ProcessBuilder pb = new ProcessBuilder("grep", "-r", "foo"); 
pb.directory(new File("myDir")); 
Process p = pb.start(); 
InputStream in = p.getInputStream(); 
//Do whatever you prefer with the stream 
+0

Javaでそれをしないとどうしていいのか説明してください。 – bezmax

+0

String.contains()は文字列の各バイトをスキャンして、一致文字列の最初の文字を探します。最初に一致するcharが見つかるたびに、文字列の残りの部分との一致を試みます。せいぜい、それは線形時間でO(n)で実行され、文字列検索のためのより良いアルゴリズムがあります。 Grepは改訂されたBoyer-Moore algoを使用します。これははるかに迅速に検索します。ネイティブのCコードなので、動的な翻訳は必要ありません。 – algolicious

+0

このアルゴリズムはJavaで実装することができます。すでにそれを使用しているライブラリがあります。さらに、Javaで実装すると、クロスプラットフォームとなり、外部ツールに依存しなくなります。したがって、私はあなたのステートメント '私は文字列の一致のためのファイルシステムを検索するためにJavaを使用しないで'に同意します。 – bezmax

0
  1. スレッドを使用してくださいBufferedReader

  2. を使用してみてください:あなたは、はるかに効率的にテキストファイルがここに見つけることができると、それを行う方法についてのチュートリアルをLuceneの持つファイルをインデックスして検索することができます。並行してファイルを検索すると、検索時間を短縮できます。

+0

IOオーバーヘッドのためスレッドからのパフォーマンスが大幅に向上することはありません。 – bezmax

+0

@Max IOを高く設定しないと、より多くのスレッドで実行するチャンスが得られますか?また、現在のすべてのマルチコアで、スレッディングはここでスループットを向上させるはずです。もしこれが当てはまらないなら、私を修正してください... – Nrj

+0

多くの要因が関係しているので、IOを行っているスレッドを見積もるのは非常に難しいです。問題は、テキストファイルをスキャンしているときに、基本的に100%のIOを使用してファイルを読み取っていることです。アプリケーションのオーバーヘッドです。しかしIOの100%の場合、(データ処理はほとんど行われないため)わずかな割合のCPUしか使用されません。異なるファイルを読み込むために複数のスレッドを使用することは、IOも並列化できる場合にのみ役立ちます(カスタムドライバを使用したRAIDアレイでも可能ですが、わかりません)。 – bezmax

1

(上記のコメントに応答するだけの小さな最適化、。)

  if(!caseSensitive) 
      { 
       searchString = searchString.toLowerCase(); 
      } 
      while (true) { 
       String line = bufferedReader.readLine(); 
       if (line == null) 
        break; 
       if(!caseSensitive) 
       { 
        line = line.toLowerCase(); 
       } 
       if(!exactMatch) 
       { 
        if (line.contains(searchString)) { 
         // System.out.println(line); 
         cnt += StringUtils.countMatches(line, 
           searchString); 
        } 
       } 
関連する問題