Swift でたらい回し関数

以前 RubyPython と C でいわゆる「たらい回し関数」のベンチマークをやってみましたが(参照)、Swift 3.0 でもやってみました。

コードは以下。無様ですがお許しを。

import Glibc

func tak(_ x: Int,_ y: Int,_ z: Int) -> Int {
    if x <= y {
        return y
    } else {
        return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y))
    }
}

let x, y, z: Int?
let ar = CommandLine.arguments
if ar.count == 4 {
    x = Int(ar[1]); y = Int(ar[2]); z = Int(ar[3])
} else {
    (x, y, z) = (10, 5, 0)
}
print("tak(\(x), \(y), \(z)) = \( tak(x!, y! ,z!) )")

結果。インタプリタで。

tak(Optional(12), Optional(6), Optional(0)) = 12

real	0m0.239s
user	0m0.216s
sys	0m0.020s

コンパイルして。

tak(Optional(12), Optional(6), Optional(0)) = 12

real	0m0.085s
user	0m0.084s
sys	0m0.000s



インタプリタだと Ruby(3.3倍)や Python(6.1倍)よりだいぶ速いし、コンパイルすると C とほぼ同じ(user で比較)。うーん、すごいですねえ…。


※追記
Swift 3.1-dev だと、最終行はこう書かないといけないようです。面倒になりました。

print("tak(" + String(describing: x) + ", " + String(describing: y) + ", " + String(describing: z) + ") = " + String(describing: tak(x!, y! ,z!)) + ")")