読者です 読者をやめる 読者になる 読者になる

読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

Collection Typeを使う重い計算にSwiftを使うにはまだ時期が早い?

アルゴリズムに専念できる「高級」言語でコンピュータ囲碁をやってみたいと思い、Swiftを選択してみました。
原始モンテカルロ碁を実装してみて、結論として、残念ながらSwift 2ではまだこういう計算は大変という結論を得ました。

以下、ボトルネックとなったところ。

// reference : Mr. Yamashita's sample code in lectures in Dentsu University

let dir4 = [1, WIDTH, -1, -WIDTH]

func count_liberty_sub(tz: Int, color: Int, inout liberty: Int, inout stone: Int) {
    ...
    for dir in dir4 {
        ....
        if board[z] == color {
            count_liberty_sub(z, color: color, liberty: &liberty, stone: &stone)
        }
    }
}

このコードが重いのです。dir4はグローバルな定数ですが、関数count_liberty_subで使う時、Swiftは礼儀正しく、swift_bridgeObjectRetainを実行し、その中で_swift_retain_を実行します。
そして関数が戻る時には_swift_release_を実行。
このretainとreleaseがそれぞれ1-2msかかるので、他の処理にほとんど時間がかからなくても重い処理になります。

(試しにdir4に配列リテラルを直接描いてみたら、配列リテラルの生成とリリースが都度発生して悪化しました。)

グローバルな定数配列でARCをしても仕方ないと思うのですが、どういうものなのでしょう?

ちなみに、Optimization LevelはFast, Whole Module Optimizationです。

Swiftベンチマークでいい数字出しているようですが、全体に、ArrayやSetなどCollection Typeを使うとまだスクリプト言語並みに重いという印象です。