2015-11-24 11 views
10

String.substringのパフォーマンス上の考慮事項に関する質問。 Java 1.7.0_06より前のバージョンでは、String.substring()メソッドは、親と同じ基本的なchar配列を共有していたが、オフセットと長さが異なる新しいStringオブジェクトを返しました。プログラマは、このようなコードを記述するために使用される、わずかな部分文字列を保持するために必要とされたときに、メモリ内の非常に大きな文字列を保つ避けるために:基底のchar []値のコピーを作成するString.substring()

s = new String(queryReturningHugeHugeString().substring(0,3)); 

以降1.7.0_06から、新しいを作成する必要はなかったですStringであるため、オラクルのStringの実装では、部分文字列は基になる文字配列を共有しないためです。

私の質問は、将来のリリースでchar[]共有に戻っておらず、単にs = s.substr(...)を共有することができますか、または新しい文字列を明示的に作成する必要がありますか? JREはもう一度共有実装を使用し始めますか?

+1

正確な回答ではありませんが、ここでの非常に良い答えhttp://stackoverflow.com/a/20275133/2796832が役立ちます。もしあなたが本当に必要とするのであれば、その答えから 'getValueLength'を使用して、あなたのコードにフラグを立てることができます。 –

+2

@JonahGraham、悪いアドバイス。これはJava-9で既に破損している可能性があります: 'char []'配列はそこで 'byte []'に置き換えられることが予想されます。リフレクションを介してプライベートなJDKフィールドにアクセスすることは一般的には良い考えではありません。 –

+0

@TagirValeev TBH私はそのコメントを回答として考えていましたが、それは私に不快感を与えました。私はOPが詳細な解析を行って、コード内の余分な複雑さが時期尚早の最適化ではないことを確認したと確信しています。しかし、私は将来の読者が同じ注意と注意を払うとは思っていません。とにかく、あなたの答えはいいです+1 –

答えて

6

Stringの実際の表現は内部的な実装の詳細なので、わからないことがあります。しかし、オラクルのエンジニアの公聴会(最も顕著なのは@shipilev)によれば、それは変更される可能性は非常に低いです。これはメモリリークの可能性に対処するだけでなく、String内部を単純化するためにも行われました。単純な文字列では、String deduplicationCompact Stringsのような多くの最適化手法を実装する方が簡単です。

+0

実際には、ストリングの重複の存在は、われわれがとにかく部分文字列表現について心配する必要はないことも示しています。 JVMのガベージコレクタが等価のインスタンスが同じ配列を共有できるように文字列にパッチを当てることができれば、JVMベンダーが共有部分文字列に戻ることを決定した場合でも部分文字列にパッチを当てることができると想定するために、 (オフセット+長さ)表現。 – Holger

関連する問題