You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift十万级数组过滤性能过慢,求高效优化方案

性能优化方案

1. 正确使用Set进行集合运算(核心优化)

你的第二种实现没用到Set的核心优势——O(1)时间复杂度的contains操作,反而还是在遍历数组做contains,等于白转Set。正确的做法是把两个数组都转为Set,利用集合的内置运算直接求差异:

DispatchQueue.global().async {
    let beforeSet = Set(beforeStringList)
    let afterSet = Set(afterStringList)
    
    // 已删除元素:仅存在于before数组
    let deletedRows = beforeSet.subtracting(afterSet)
    // 新增元素:仅存在于after数组
    let addedRows = afterSet.subtracting(beforeSet)
    
    // 批量处理结果,避免在循环里做print这类IO操作
    print("已删除条目数:\(deletedRows.count)")
    print("新增条目数:\(addedRows.count)")
}
  • 时间复杂度从原来的O(n*m) 降到O(n+m),10万级数据能在毫秒级完成计算。
  • Set的哈希查找是Swift内置优化过的,完全能应对这个量级的数据。

2. 在SQLite层面直接计算差异(最优方案)

既然数据来自SQLite表,没必要把全量数据加载到内存再对比,直接让数据库引擎帮你做差异计算——这是数据库的强项,尤其是给字段加索引后,速度会远超内存处理:

查询已删除数据(原表有,新表无)

SELECT value FROM before_table
EXCEPT
SELECT value FROM after_table;

查询新增数据(新表有,原表无)

SELECT value FROM after_table
EXCEPT
SELECT value FROM before_table;

或者用LEFT JOIN实现(效果一致):

-- 已删除数据
SELECT b.value FROM before_table b
LEFT JOIN after_table a ON b.value = a.value
WHERE a.value IS NULL;
  • 优势:不需要加载10万条数据到内存,减少IO和内存占用;数据库对这类查询有索引优化,速度更快。

3. 辅助优化细节

  • 避免不必要的IO操作:不要在遍历/过滤过程中做print,先计算完所有差异再批量输出,IO操作会严重拖慢处理速度。
  • 提前去重:如果原数组存在大量重复字符串,转Set的过程已经自动去重,能减少后续处理的数据量。
  • 内存控制:如果字符串本身极大(比如长文本),可以考虑分批从数据库读取并对比,避免一次性占用过多内存。

内容的提问来源于stack exchange,提问作者ez4nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:00:59