Avatar
まず、クロージャがaとbをコピーしてるというのは無さそうです。nonescapeなクロージャはスタック上の値をポインタ参照するので。 で、TimeProfilerで調べてみたら、Matrix.initに渡してるクロージャの中のmapとreduceが、CountableRangeに対するprotocol witness呼び出しをしていたんで、そこらへんがインライン化されてないっぽいです。 Matrix.multiply自体はSpecializeされているぽいけど、Matrix.initのクロージャの中身が最適化されてない (edited)
5:54 AM
試しに Matrix.initの中身だけ手動で書いたら、 swifty(1): 9.03 pointer(2): 0.18 に対して、 forloop(3): 1.93
5:54 AM
public static func multiply3<p>(a: Matrix<R, n, m>, b: Matrix<R, m, p>) -> Matrix<R, n, p> { assert(a.cols == b.rows, "Mismatching matrix size.") return Matrix<R, n, p>(rows: a.rows, cols: b.cols, type: (a.type == b.type) ? a.type : .Default) { (i, k) -> R in var x = R.zero for j in 0..<a.cols { x = x + a[i, j] * b[j, k] } return x } }
5:55 AM
50倍ぐらい差があるところを10倍差ぐらいまで追いついた。