I am trying to build a data structure in Swift that maps an integer to an array of objects (a dictionary with an int key and a key as a value). The objects are extremely small and they simply wrap UIColor and Int. I have two implementations that use a Swift array as the type of the value of a dictionary, while the other uses NSMutableArray as the type of the value. My C object code is very fast, but my Swift code is very slow. Ideally, I would not want to use NSMutableArray and would like to save it as a Swift array. For this, I write an algorithm and performance, I noticed some overhead with objC_msgSend. Can someone help me optimize my Swift code? Am I doing something wrong or is it just a byproduct of a quick treatment array like value types? If so, I would like to understandwhy is the value type in this case so slow, what are my parameters, and how can this scenario scale in the future? Below I posted a code snippet and the resulting criteria:
Array quick code:
let numColors = colorCount(filter: filter, colorInfoCount: colorInfo.count)
var colorCountsArray: [Int] = [Int]()
var countToColorMap: [Int:[CountedColor]] = [Int:[CountedColor]](minimumCapacity: capacity)
var topColors = [CountedColor]()
var startTime = CACurrentMediaTime()
for (color, colorCount) in colorInfo {
colorCountsArray.append(colorCount)
if countToColorMap[colorCount] != nil {
countToColorMap[colorCount]?.append(CountedColor(color: color, colorCount: colorCount))
} else {
countToColorMap[colorCount] = [CountedColor(color: color, colorCount: colorCount)]
}
}
var endTime = CACurrentMediaTime()
print("Time after mapping: \(endTime - startTime)")
Fast performance:
Time after mapping: 45.0881789259997
NSMutableArray Code:
let numColors = colorCount(filter: filter, colorInfoCount: colorInfo.count)
var colorCountsArray: [Int] = [Int]()
var countToColorMap: [Int:NSMutableArray] = [Int:NSMutableArray](minimumCapacity: capacity)
var topColors = [CountedColor]()
var startTime = CACurrentMediaTime()
for (color, colorCount) in colorInfo {
colorCountsArray.append(colorCount)
if countToColorMap[colorCount] != nil {
countToColorMap[colorCount]?.add(CountedColor(color: color, colorCount: colorCount))
} else {
countToColorMap[colorCount] = NSMutableArray(object: CountedColor(color: color, colorCount: colorCount))
}
}
var endTime = CACurrentMediaTime()
print("Time after mapping: \(endTime - startTime)")
NSMutableArray Performance:
Time after mapping: 0.367132211999888
The colorInfo object is a dictionary that maps UIColor objects to an integer representing an account. The code, in fact, is inverse, displays this by matching an integer with a UIColor array (its array, because several colors can have the same number). ColorInfo contains 60,000 character pairs UIColor, Int.