Swift拼接JSON时判断fullJSON.count的代码运行极慢是什么原因?
性能问题根本原因
Swift 中 String 的 count 属性的时间复杂度为 O(n),而非你以为的 O(1)。
因为 Swift 的 String 是 Unicode 兼容的集合类型,每个字符为扩展字形簇,长度不固定,每次调用 count 都需要遍历整个字符串的全部字节才能统计出准确的字符数量。
当你循环拼接 JSON 时,fullJSON 字符串会随着循环次数增加变得越来越长,每次执行 fullJSON.count > 1 都要重新遍历整个长字符串,当数据量较大时,总时间复杂度会飙升到 O(n²),这就是代码变慢的核心原因。你注释掉这段判断后,不再触发高频的 count 计算,性能自然恢复正常。
注意:你注释分隔符拼接逻辑只是临时解决了性能问题,最终生成的 JSON 没有逗号分隔不同对象,属于非法格式,传给后端接口必然会出错。
优化方案
以下方案都可以同时解决性能问题和 JSON 格式合法性问题:
- 方案1:用布尔标记替代长度判断
新增一个变量标记是否是第一个待拼接的 JSON 元素,判断逻辑为 O(1),无额外性能开销:var fullJSON = "[" var isFirstItem = true // 新增标记位 for job in jobs { if let json = job.toJSON() { if !isFirstItem { fullJSON += ",\n " } else { isFirstItem = false } fullJSON += json } else { // 原有错误处理逻辑 print("COULDN'T JSON \(job.name ?? "")") callback("Error decoding \(job.name ?? "")") return } } fullJSON += "]" - 方案2:用数组拼接后统一合并(更推荐)
先把所有合法的 JSON 字符串存入数组,再调用系统优化过的joined(separator:)方法拼接,代码更简洁,性能更高:// 先收集所有合法的JSON字符串 var jsonSegments = [String]() for job in jobs { guard let json = job.toJSON() else { print("COULDN'T JSON \(job.name ?? "")") callback("Error decoding \(job.name ?? "")") return } jsonSegments.append(json) } // 一次性拼接成完整JSON let fullJSON = "[" + jsonSegments.joined(separator: ",\n ") + "]" - 方案3:使用系统原生JSON序列化(最规范)
完全避免手动拼接JSON的出错风险,直接用Codable或JSONSerialization把jobs数组序列化为标准JSON,系统接口经过高度优化,性能远高于手动拼接。
内容的提问来源于stack exchange,提问作者drago
相关产品推荐
相关产品推荐

