In Swift, I'm trying to build a large collection of items. When creating elements in CoreData on-the-go, this is very speedy. However when trying to keep an index to those items, creating an array Swift has a large performance impact. The code below is a benchmark between NSMutableArray and Swift's Array. When ran in the iOS Simulator, the Swift Array is around 8x slower. Why is this, can it be improved, or should it improve over the as Apple releases new builds of Xcode/Swift?
Code:
var start: NSDate
var time: NSTimeInterval
var batch = 1000000
var rate: Double
var oArr = NSMutableArray(capacity: batch)
start = NSDate()
for i in 1..batch {
oArr.addObject(i)
}
time = -start.timeIntervalSinceNow
rate = Double(batch) / Double(time)
println("NSMutableArray \(batch) appends in \(time) sec: \(rate)/sec")
var sArr = Int[]()
start = NSDate()
for i in 1..batch {
sArr += i
}
time = -start.timeIntervalSinceNow
rate = Double(batch) / Double(time)
println("Array<Int> \(batch) appends in \(time) sec: \(rate)/sec")
Output in simulator (beta 2) 794%:
NSMutableArray 1000000 appends in 1.17320102453232 sec: 852368.843096295/sec
Array<Int> 1000000 appends in 9.31138801574707 sec: 107395.374170729/sec
Output in simulator (beta 3):
NSMutableArray 1000000 appends in 0.71416300535202 sec: 1400240.55083487/sec
Array<Int> 1000000 appends in 5.00839000940323 sec: 199664.961818569/sec
Output on iPhone 5 (beta 3 on iOS 7.1):
NSMutableArray 1000000 appends in 8.79256194829941 sec: 113732.494110367/sec
Array<Int> 1000000 appends in 55.6573320031166 sec: 17967.084730975/sec
Update:
with Xcode beta-3, with a console program on a MacBook Pro 2 GHz Intel Core i7, I get these numbers with the original test (also fixed syntax due to minor grammar changes):
Debug (-O0):
NSMutableArray 1000000 appends in 0.782136023044586 sec: 1278549.9843203/sec
Array<Int> 1000000 appends in 5.56463801860809 sec: 179706.208500177/sec
Release (-Os):
NSMutableArray 1000000 appends in 0.14977502822876 sec: 6676680.43081684/sec
Array<Int> 1000000 appends in 0.124498963356018 sec: 8032195.3937913/sec
Release (-Ofast):
NSMutableArray 1000000 appends in 0.151567995548248 sec: 6597698.91646863/sec
Array<Int> 1000000 appends in 0.122538030147552 sec: 8160731.80543105/sec
It doesn't seem fair that you're telling the NSMutableArray
how much space it needs to allocate right up front but making the Swift array re-allocate itself with every single append. This makes the Swift version stupid fast, although it's kind of unfair in the other direction:
var sArr = Array<Int>(count: batch, repeatedValue: 0)
start = NSDate()
for i in 0..batch {
sArr[i] = i
}
Edit: It looks like NSMutableArray
doesn't actually use the capacity you provide to speed itself up, so maybe never mind?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With