2013-06-06 6 views
7

私たちはJava SAXを使って、本当に大きなXMLファイルを解析しています。私たちのcharacters実装には、次のようになります。Javaのchar []、start、lengthから文字列を作成する効果的な方法

@Override 
public void characters(char ch[], int start, int length) throws SAXException { 
    String value = String.copyValueOf(ch, start, length); 
    ... 
} 

(SAXで渡さch[]配列がかなり長くなる傾向にある)しかし、我々は最近、いくつかのパフォーマンスの問題を得ているし、プロファイラは、私たちを示している私達のCPUの20%以上使用量はString.copyValueOf(これはフードの下でnew String(ch,start,length)を呼び出した)の上です。

String.copyValueOf(ch, start, length)またはnew String(ch,start,length)より文字、開始インデックス、および長さの配列から文字列を取得する方法がありますか?

+0

悪化する可能性がありますが、 'StringBuilder'を試してみましたか? 'new String(ch、start、length)'は配列をコピーするだけですが、 'StringBuilder'がどのくらい速く動作するかはわかりません。 – Djon

+1

作成されたStringは返されません。あなたはそれで何をしていますか?その文字列で行われる処理は、startとlengthを使ってchar []で直接行うこともできますか? – Fildor

+0

@Fildorええ、私はそれについて考えました。しかし、私たちはストリングとして扱うところで、多くの異なる操作を行います。 char配列を操作するのは非常に困難です(少なくともコードは実際には醜いでしょう)。 –

答えて

4

良い質問ですが、その答えはです。です。

これは、Stringオブジェクト構成のいずれかが配列コピー方式を使用しているためです。 Stringオブジェクトは不変でなければならず、その内部文字列配列表現は外側の変更からカプセル化されているため、存在する配列上に直接構築することはできません。

さらに、あなたのケースでは、フラグメントの配列があります。任意の方法で別の配列のフラグメントにStringオブジェクトを構築することは不可能です。

1

@Andremoniyで述べたように、Stringオブジェクトを使用する場合は、必ず作成して内容をコピーする必要があります。

パーサを高速化できる唯一の可能性は、新しく構築される文字列オブジェクトの数を最小限に減らすことです。

xml-structureのすべての要素には、開始タグと終了タグの間に生データが含まれています。

そのため、データが関心のある要素内にある場合にのみ、文字列を作成することをお勧めします。さらに、私は可能な要素をどうにか制限することを提案します。たとえば、階層レベルまたは親要素によって、文字列比較の数を減らします。しかし、これはXML構造に依存します。 charactersがappropiateかもしれない要素レベルでのStringBuilderを保持し、単一のタグ内に複数回呼び出されるかもしれないことをおそらく関連して

protected boolean readChars = false; 
protected int level = -1; 

@Override 
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
    ++level; 

    if (level == 4) { 
     if (qName.equalsIgnoreCase("TextElement")) { 
      readChars = true; 
     } 
    } 
} 

@Override 
public void characters(char ch[], int start, int length) throws SAXException { 
    if (readChars) { 
     String value = String.copyValueOf(ch, start, length); 
     ... 
     readChars = false; 
    } 
} 

@Override 
public void endElement(String uri, String localName, String qName) throws SAXException { 
    --level; 
} 
1

、。これはSystem.arrayCopyです。

関連する問題