Hi there.
I found that Swift's multidimensional arrays are very slow on certain operations. I was aware of the performance issues with multidimensional arrays because I had read the Swift forum and Reddit (c.f. https://forums.swift.org/t/low-efficiency-multidimensional-array-problem/5717, https://www.reddit.com/r/swift/comments/2fqldf/slow_2d_array_multiply/), but the following is a more extreme example. Here is my code:
// 001.swift
let H = 10
let W = 100000
var arr = [[Int]](repeating: [Int](repeating: 0, count: W), count: H)
for i in 0..<H {
for j in 0..<W {
arr[i][j] = arr[i][j]
}
}
I experimented with different H and W without changing H*W=1000000, and it seems that as W increases, the execution time increases rapidly.
The following code was used to measure execution time:
// logger.swift
import Foundation
let filePath = "./{executable}"
let task = Process()
task.launchPath = filePath
let startTime = Date()
try task.run()
task.waitUntilExit()
let elapsed = Date().timeIntervalSince(startTime)
print("Execution time: \(elapsed) s")
On the other hand, when assigning values other than the elements of arr, for example, 002.swift and 003.swift, the execution seems to be fast.
// 002.swift
let H = 10
let W = 100000
var arr = [[Int]](repeating: [Int](repeating: 0, count: W), count: H)
for i in 0..<H {
for j in 0..<W {
arr[i][j] = i + j
}
}
// 003.swift
let H = 10
let W = 100000
var arr = [[Int]](repeating: [Int](repeating: 0, count: W), count: H)
var arr2 = [[Int]](repeating: [Int](repeating: 0, count: W), count: H)
for i in 0..<H {
for j in 0..<W {
arr[i][j] = arr2[i][j]
}
}
More oddly, it runs just as fast when reassigned via the temporary variable.
// 004.swift
let H = 10
let W = 100000
var arr = [[Int]](repeating: [Int](repeating: 0, count: W), count: H)
for i unsunsin 0..<H {
for j in 0..<W {
let tmp = arr[i][j]
arr[i][j] = tmp
}
}
Here is a table of execution time (sec):
|
H=1, W=10ā¶ |
H=10, W=10āµ |
H=10², W=10ⓠ|
H=10³, W=10³ |
H=10ā“, W=10² |
H=10āµ, W=10 |
H=10ā¶, W=1 |
001.swift |
464.240 |
21.267 |
4.732 |
0.936 |
0.932 |
1.000 |
1.264 |
002.swift |
0.730 |
0.801 |
0.729 |
0.728 |
0.731 |
0.800 |
0.868 |
003.swift |
0.535 |
0.399 |
0.464 |
0.464 |
0.797 |
1.202 |
1.200 |
004.swift |
0.734 |
0.734 |
0.734 |
0.734 |
0.730 |
0.794 |
1.264 |
According to these results, almost the same process can be 400 to 500 times slower, depending on how it is written. And here is my environment:
- M1 MacBook Air (Early 2020)
- macOS Ventura 13.2.1
- Swift 5.7.2
Any good explanation?