数组 – Swift中的字典与Mutable Array作为值表现得非常慢?如何
发布时间:2020-12-14 05:23:05 所属栏目:百科 来源:网络整理
导读:我试图在 Swift中构建一个数据结构,将Integer映射到一个对象数组(一个字典,其中int为键,数组为value).对象非常小,它们只需包装UIColor和Int.我有两个实现,一个使用Swift数组作为Dictionary的值类型,而另一个使用NSMutableArray作为值类型.我的Objective-C代
我试图在
Swift中构建一个数据结构,将Integer映射到一个对象数组(一个字典,其中int为键,数组为value).对象非常小,它们只需包装UIColor和Int.我有两个实现,一个使用Swift数组作为Dictionary的值类型,而另一个使用NSMutableArray作为值类型.我的Objective-C代码执行速度非常快,但我的Swift代码运行得非常慢.理想情况下,我不想使用NSMutableArray,并希望将其保留为Swift数组.原因是我正在编写算法和性能问题,我注意到了objC_msgSend的一些开销.任何人都可以帮我优化我的Swift代码吗?我做错了什么,或者这只是快速处理数组作为值类型的副产品?如果是,我想理解为什么值类型在这种情况下表现得如此之慢,我的选择是什么,以及这种情况如何能够在未来扩展?下面我发布了一个代码段和结果基准:
Swift数组代码: 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)") 迅捷表现: Time after mapping: 45.0881789259997 NSMutableArray代码: 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表现: Time after mapping: 0.367132211999888 colorInfo对象是将UIColor对象映射到表示计数的Integer值的字典.代码本质上反向映射,将整数映射到UIColor数组(它是一个数组,因为多个颜色可以具有相同的计数). colorInfo里面有60,000个UIColor,Int键值对.
写入时复制是一件棘手的事情,您需要仔细考虑共享一个您正在尝试修改的结构的内容.罪魁祸首就在这里.
countToColorMap[colorCount]?.append(CountedColor(color: color as! UIColor,colorCount: colorCount)) 这将生成一个临时值,该值将被修改并重新放入字典中.由于两个“事物”正在查看相同的底层数据结构(字典和附加),因此它会强制执行写入时复制. 解决这个问题的秘诀是确保修改它时只有一个副本.怎么样?把它拿出字典.替换这个: if countToColorMap[colorCount] != nil { countToColorMap[colorCount]?.append(CountedColor(color: color as! UIColor,colorCount: colorCount)) } else { countToColorMap[colorCount] = [CountedColor(color: color as! UIColor,colorCount: colorCount)] } 它的运行时间为: Elapsed Time: 74.2517465990022 53217 有了这个: var countForColor = countToColorMap.removeValue(forKey: colorCount) ?? [] countForColor.append(CountedColor(color: color as! UIColor,colorCount: colorCount)) countToColorMap[colorCount] = countForColor 它的运行时间为: Elapsed Time: 0.370953808000195 53217 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |