文字列への変更。 Java 7

みなさんこんにちは。 ウクライナでの最近の出来事はどういうわけか私をHabrrから遠ざけましたが、今では、多少なりともすべてが良くなり、私は通常の仕事のリズムに戻って、下書きの私の投稿をいくつか思い出しました。 Javaの8番目のバージョンのリリースに関連して、この投稿はすでにいくらか古くなっているかもしれませんが、良さは消えません。

そのため、ある晩、別のコードを最適化して、誤ってStringを調べたところ、文字列のクラスが同じではないことがわかりました。 文字列はおそらく最も一般的なタイプの1つなので、多くの人が変更について知りたいと思うでしょう。



最適化されたString.split()メソッド


単一文字のパラメーターの場合、行分割方法がより高速になりました。 これで、メソッドはregexpをまったく使用せず、indexOfがループで適用されます。

それは

public String[] split(String regex, int limit) { return Pattern.compile(regex).split(this, limit); }
      
      





になりました

 public String[] split(String regex, int limit) { if (((regex.value.length == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || ...)) { ... while ((next = indexOf(ch, off)) != -1) { ... } ... return result; } return Pattern.compile(regex).split(this, limit); }
      
      







2つのフィールドが削除されました


第7回Javaの第6回更新以降、行クラスから2つのフィールドが削除されました。

 private int offset; private int count;
      
      





おそらく覚えているように、これらのフィールドはサブストリングメソッドを呼び出すときに使用されました。 フィールドの目的は、メソッドの複雑さを軽減し、既存の配列へのリンクを使用して文字列文字の新しい配列を作成しないようにすることです。 また、状況によっては、 既知のメモリリークが発生する可能性があります。 現在、文字列サイズは8バイト小さくなり、漏れの問題は永遠に解決されました。





新しいハッシュアルゴリズム


 private transient int hash32 = 0; int hash32() { int h = hash32; if (0 == h) { // harmless data race on hash32 here. h = sun.misc.Hashing.murmur3_32(HASHING_SEED, value, 0, value.length); // ensure result is not zero to avoid recalcing h = (0 != h) ? h : 1; hash32 = h; } return h; }
      
      





2つの削除されたフィールドの代わりに、1つの新しい整数-hash32が現れました。 文字列の新しいハッシュを保存するように設計されています。 新しいハッシュは、 たとえばhashmapで使用されます

 transient int hashSeed = useAltHashing ? sun.misc.Hashing.randomHashSeed(this) : 0; final int hash(Object k) { int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } ... }
      
      





新しいハッシュアルゴリズムにより、文字列のハッシュの分布が改善されるはずです(既存のハッシュハッシュよりも具体的に優れているものは見つかりませんでした。コメントで教えてください)。 新しいハッシュ関数はデフォルトで無効になっています。有効にするには、オプション「jdk.map.althashing.threshold」が必要です。 ただし、6番目の更新プログラムのリリース直後に、非常に競争の激しいマルチスレッド環境では、sun.misc.Hashing.randomHashSeed()メソッドのため、randomHashSeedメソッドはRandomキューはAtomicLongに基づいているため、パフォーマンスの問題が発生しました。

アップデート40以降、このバグはすでに修正されています。



Java 8アップデート


私が言われたように、Java 8では、新しいハッシュアルゴリズムは削除されました。



分割最適化


そのため、ほとんどの開発者が標準クラスの内部メソッドを調べることはめったにありません。 それでも、内部には最適化の範囲がたくさんあります。 同じことがライン分割法でも起こりました。 コードの重要なセクションでは、次の代わりに:

 someString.split("[_,;,-]");
      
      





できること:

 private static final Pattern PATTERN = Pattern.compile("[_,;,-]"); PATTERN.split(someString);
      
      





また、splitメソッドの約2倍のパフォーマンス向上が得られます。



All Articles