2011-09-14 8 views
1

私はもともとStringTokenizerは、約1,500のトークンが含まれており、プログラムが正常に動作読んで、生のテキストStringにおけるプロセスデータはStringTokenizerのJavaパフォーマンスの問題StringTokenizerは

を使用してプログラムを持っています。しかし、生のコンテンツが増加し、現在は約12,000のトークンになり、CPU消費量が大幅に増加しています。

私は問題を調査し、原因を特定しようとしています。プログラムはwhileループを使用してトークンが残っているかどうかをチェックし、読み取られたトークンに基づいて別のアクションが実行されます。私はこれらの異なる行動をチェックして、その行動が改善できるかどうかを確認しています。

一方、長い1つの長さを扱うのがStringTokenizerの場合は、処理するのに比べてCPUが10個短いと聞いてみたいと思います。StringTokenizer s。

+8

StringTokenizerで、あなたがやっていることではないと確信していますか?問題を示す短くしかし完全なプログラムを示してください。 –

+0

私はそうは思わない。文字列はランダムアクセスです。長い文字列の場合は減速しません。 – Thilo

+1

'StringTokenizer'には、長い入力に対して爆発するものはありません。それは周囲のコードの何かでなければなりません。 – Barend

答えて

0

代わりに、新しいScannerクラスを使用してみませんか?スキャナはストリームとファイルを使用して構築できます。しかし、古いStringTokenizerよりも効率的かどうかはわかりません。

1

StringTokenizerの使用は、StringTokenizer java docに従ってお勧めしません。 使用することはできますが、廃止されることはありません。それだけが推奨されていません。ここに書かれているものです。

「StringTokenizerは、その使用は、新しいコードに落胆しているが、互換性 の理由のために保持されている従来のクラスであることは、この機能を求めている誰もがString の分割方法を使用することを をお勧めします。代わりにjava.util.regexパッケージを使用してください。

次の記事を確認してください。それはあなたがやろうとしているのと同じことをするための様々な方法の非常に素晴らしい例を持っています。

performance-of-stringtokenizer-class-vs-split-method-in-java

あなたはそこに提供されているサンプルを試してみて、あなたのための最高の作品かを見ることができます。

+0

ありがとうA.J. あなたのお勧めの投稿は、私の問題を解決するのに非常に役立ちます。 –

1

まず、ご意見ありがとうございます。先週末、私は改訂されたプログラムを使用して実際のデータを用いてストレステストを実施しました。そして、私の問題が解決されたことを嬉しく思います(A.J.^_ ^)。私は私の発見を共有したいと思います。

A.J.の例を勉強した後、私はStringTokenizerと "indexOf"(Regexは私の状況ではStringTokenizerと比較してさらに悪い)を使ってデータを読み込んで処理するいくつかのテストプログラムを実行しました。私のテストプログラムは、24メッセージ(それぞれ〜12000トークン)を処理するために必要なミニ秒数を数えます。

StringTokenizerは〜2700msが必要で、 "indexOf"は〜210msしかかかりません!

私はその後、(最小限の変更で)このように私のプログラムを改訂し、最後の週末、実ボリュームでテストしてみた:

オリジナルプログラム:

public class MsgProcessor { 
    //Some other definition and methods ... 

    public void processMessage (String msg) 
    { 
     //... 

     StringTokenizer token = new StringTokenizer(msg, FieldSeparator); 
     while (token.hasMoreTokens()) { 
      my_data = token.nextToken(); 
      // peformance different action base on token read 
     } 
    } 
} 

そして、ここで使用してプログラムを更新されます"のindexOf":

public class MsgProcessor { 
    //Some other definition and methods ... 
    private int tokenStart=0; 
    private int tokenEnd=0; 

    public void processMessage (String msg) 
    { 
     //... 
     tokenStart=0; 
     tokenEnd=0; 

     while (isReadingData) { 
      my_data = getToken(msg); 
      if (my_data == null) 
       break; 
      // peformance different action base on token read ... 
     } 
    } 

    private String getToken (String msg) 
    { 
     String result = null; 
     if ((tokenEnd = msg.indexOf(FieldSeparator, tokenStart)) >= 0) { 
      result = msg.substring(tokenStart, tokenEnd); 
      tokenStart = tokenEnd + 1; 
     } 
     return result; 
    } 
} 
  • 元のトークンには "null"データがないことに注意してください。 FieldSeparatorが見つからない場合、「getToken(msg)」はnullを返します(「トークンをもう使用しない」というシグナルとして)。