1. ホーム
  2. java

StringのhashCode()はなぜ0をキャッシュしないのでしょうか?

2023-10-17 10:12:46

質問

Java 6 の String のソースコードで、hashCode が 0 以外の値のみをキャッシュすることに気づきました。 パフォーマンスの違いは、次のスニペットで示されます。

public class Main{
   static void test(String s) {
      long start = System.currentTimeMillis();
      for (int i = 0; i < 10000000; i++) {
         s.hashCode();
      }
      System.out.format("Took %d ms.%n", System.currentTimeMillis() - start);
   }
   public static void main(String[] args) {
      String z = "Allocator redistricts; strict allocator redistricts strictly.";
      test(z);
      test(z.toUpperCase());
   }
}

ideone.comでこれを実行する を実行すると、次のような出力が得られます。

Took 1470 ms.
Took 58 ms.

そこで質問なのですが

  • なぜStringのhashCode()は0をキャッシュしないのでしょうか?
  • Java の文字列が 0 にハッシュする確率はどのくらいですか?
  • 0 にハッシュする文字列に対して毎回ハッシュ値を再計算することによるパフォーマンス上のペナルティを回避する最善の方法は何でしょうか?
  • これは値をキャッシュするベストプラクティスの方法ですか?(すなわち、1 つを除くすべてをキャッシュしますか?)?

あなたの娯楽のために、ここでの各行は0にハッシュされる文字列です。

pollinating sandboxes
amusement & hemophilias
schoolworks = perversive
electrolysissweeteners.net
constitutionalunstableness.net
grinnerslaphappier.org
BLEACHINGFEMININELY.NET
WWW.BUMRACEGOERS.ORG
WWW.RACCOONPRUDENTIALS.NET
Microcomputers: the unredeemed lollipop...
Incentively, my dear, I don't tessellate a derangement.
A person who never yodelled an apology, never preened vocalizing transsexuals.

どのように解決するのですか?

あなたは何も心配しないでください。 この問題について考える方法を紹介します。

一年中文字列をハッシュ化するためだけに座っているようなアプリケーションがあるとします。 1000 個の文字列をすべてメモリ内に取り込み、ラウンドロビン方式で繰り返し 100 万回、その上で hashCode() を呼び出し、さらに 1000 個の新しい文字列を取得して、もう一度それを行うとします。

そして、文字列のハッシュコードがゼロである可能性が、実際には 1/2^32 よりはるかに大きいと仮定します。 それはきっと 多少 1/2^32よりも大きいと思いますが、それよりずっと悪い、1/2^16(平方根!これはもっと悪い!)だとしましょう。

この状況では、Oracle のエンジニアがこれらの文字列のハッシュ コードをキャッシュする方法を改善することで、他の誰よりも多くの利益を得ることができます。そこで、あなたは彼らに手紙を書いて、それを修正するように頼みます。そして彼らは、s.hashCode() がゼロであるときはいつでも、それが を即座に返します。 を返すようになりました (初回でも! 100% の改善です!)。そして、他のいかなる場合にも、パフォーマンスをまったく低下させることなく、これを実行したとしましょう。

万歳! これであなたのアプリは...えーと... 0.0015% 速くなりました!

丸1日かかっていたものが、たった23時間57分48秒になりました!

そして、私たちは、可能な限りの疑惑を与えるようにシナリオを設定したことを忘れないでください。

あなたにとって、これは価値があると思いますか?

EDITです。 数時間前にこれを投稿してから、私はハッシュコードゼロの2語フレーズを探すためにプロセッサの1つを野放しにしました。今のところ、bequirtle zorillo, chronogrammic schtoff, contusive cloisterlike, creashaks organzine, drumwood boulderhead, electroanalytic exercisable, and favosely nonconstruable と出てきています。これは約2^35の可能性のうち、完全な分布では8つしか表示されないと予想されます。完成する頃にはその数倍になっているのは明らかですが、突飛な数ではありません。それよりも、面白いバンド名やアルバム名がいくつか思いついたことが大きいです。 盗むなんてもってのほか!