オセロ評価関数高速化を、携帯電話アプリにいて行なう
とりあえず、弱いのは分かっていながらも盤面のマス毎に点数をつける方式で行なう。
素直にかけば
for(i = 0; i < 64; i++) { if (0 != (lStone & (1L << i))) nScore += anScoreList[i]; }
上のようになる。まぁもちろんこんなのじゃ遅くて使い物にならない。
ではテーブル化しましょう。
nScore = anScoreTable[0][(int)(lStone >>> 0) & 0x000000FF] + anScoreTable[1][(int)(lStone >>> 8) & 0x000000FF] + anScoreTable[2][(int)(lStone >>> 16) & 0x000000FF] + anScoreTable[3][(int)(lStone >>> 24) & 0x000000FF] + anScoreTable[4][(int)(lStone >>> 32) & 0x000000FF] + anScoreTable[5][(int)(lStone >>> 40) & 0x000000FF] + anScoreTable[6][(int)(lStone >>> 48) & 0x000000FF] + anScoreTable[7][(int)(lStone >>> 56) & 0x000000FF] ;
もちろん先にテーブルを初期化しておくわけですが。
さて、さらに速くするために、テーブルを1段ずつではなく2段ずつにします。
nScore = anScoreTable[0][(int)(lStone >>> 0) & 0x0000FFFF] + anScoreTable[1][(int)(lStone >>> 16) & 0x0000FFFF] + anScoreTable[2][(int)(lStone >>> 32) & 0x0000FFFF] + anScoreTable[3][(int)(lStone >>> 48) & 0x0000FFFF] ;
これの方がさらに速い!と思ったら、遅くなりました。
Javaは巨大な配列を参照するのが苦手なんでしょうか?
nScore = anScoreTableA[(int)(lStone >>> 0) & 0x0000FFFF] + anScoreTableB[(int)(lStone >>> 16) & 0x0000FFFF] + anScoreTableC[(int)(lStone >>> 32) & 0x0000FFFF] + anScoreTableD[(int)(lStone >>> 48) & 0x0000FFFF] ;
それならこれでどうだ!もっと遅くなった!(誤差程度だけど)
うーん、どういうことなんでしょう。
誰か教えてー!
ちなみに、この日記の更新が滞る=仕事で面白いことやってるなのでご心配なく。心配してる人がいればだけど(・3・)<最近デイブレしてないなー。