Avatar
昨日の #swtws での @omochimetaru さんの発表を見て、 SwiftyAlgebra の行列計算が遅すぎて悩んでいることについて何かヒントを頂けたらと思い、質問させていただきます。 https://github.com/taketo1024/SwiftyAlgebra/blob/master/Sources/Matrix/Matrix.swift 元々は行列の積を public static func * <p>(a: Matrix<R, n, m>, b: Matrix<R, m, p>) -> Matrix<R, n, p> { return Matrix<R, n, p>(rows: a.rows, cols: b.cols) { (i, k) -> R in // 積の (i, k) 成分を返す. // a の i 行と b の k 列の積和を計算. return (0 ..< a.cols) .map({j in a[i, j] * b[j, k]}) .reduce(0) {$0 + $1} } } のように書いていたのですが、これがサイズ 200x200 ぐらいでも 7 秒近くかかってしまい、これを次のように書き換えたところ 7秒 → 0.2 秒に改善されました。 public static func * <p>(a: Matrix<R, n, m>, b: Matrix<R, m, p>) -> Matrix<R, n, p> { // 行列の1次元グリッドを生成して Matrix を作る var grid = Array(repeating: R.zero, count: a.rows * b.cols) var p = UnsafeMutablePointer(&grid) for c in 0 ..< a.rows * b.cols { let (i, j) = (c / b.cols, c % b.cols) var (q, r) = (UnsafePointer(a.grid), UnsafePointer(b.grid)) q += a.gridIndex(i, 0) r += b.gridIndex(0, j) var x = R.zero for _ in 0 ..< a.cols { x = x + q.pointee * r.pointee q += 1 r += b.cols } p.pointee = x p += 1 } return Matrix<R, n, p>(rows: a.rows, cols: b.cols, grid: grid) } できればこういうポインタ丸出しのコードは書きたくないので(そっち方向でやるなら言語を変えた方が良さそうという気持ち)、なんとか上のような書き方のまま改善したいと思っているのですが、上の書き方がこんなにも遅い理由は思い当たるものありますか? init に渡す closure の中で行列 a, b にアクセスしてることから、丸ごとコピーされちゃったりしてるのかなと疑っています… 🤔 Thanks in advance 🙂 (edited)
Contribute to SwiftyAlgebra development by creating an account on GitHub.
🙂 1