楽しみのために、ルールにとらわれないポーカー シミュレーターに取り組んでいます。列挙のボトルネックをテストし、「一意の」配列から常に引き出されるハンドについて、興味深いボトルネックを見つけました。各バリエーションを実行する平均計算時間を 1,000,000,000 回未満で測定し、それを 100 回繰り返して、JIT と Hotspot が魔法のように機能できるようにしました。私が見つけたのは、計算時間(6ns対27ns)に違いがあることでした
public int getRank7(int ... cards) {
int q = (cards[0] >> 16) | (cards[1] >> 16) | (cards[2] >> 16) | (cards[3] >> 16) | (cards[4] >> 16) | (cards[5] >> 16) | (cards[6] >> 16);
int product = ((cards[0] & 0xFF) * (cards[1] & 0xFF) * (cards[2] & 0xFF) * (cards[3] & 0xFF) * (cards[4] & 0xFF) * (cards[5] & 0xFF) * (cards[6] & 0xFF));
if(flushes[q] > 0) return flushes[q];
if(unique[q] > 0) return unique[q];
int x = Arrays.binarySearch(products, product);
return rankings[x];
}
と
public int getRank(int ... cards) {
int q = 0;
long product = 1;
for(int c : cards) {
q |= (c >> 16);
product *= (c & 0xFF);
}
if(flushes[q] > 0) return flushes[q];
if(unique[q] > 0) return unique[q];
int x = Arrays.binarySearch(products, product);
return rankings[x];
}
問題は間違いなく for ループであり、関数の先頭に乗算を処理することではありません。各シナリオで同じ数の操作を実行しているので、これには少し困惑しています...この関数には常に6枚以上のカードがあることに気付いたので、に変更して物事を近づけました
public int getRank(int c0, int c1, int c2, int c3, int c4, int c5, int ... cards)
しかし、カードの数が増えると同じボトルネックが発生します。この事実を回避する方法はありますか? そうでない場合、同じ数の操作の for ループが非常に遅い理由を誰かが説明してくれませんか?