ios - 为什么字符串添加需要这么长时间才能构建?
问题描述
我正在添加文本UIlabel
,以及它的性能成本(我使用此链接使用了构建时间分析器)。我该如何优化这段代码?
for value in model?.offerings ?? [] {
offeringsLabel.text = offeringsLabel.text! + " | " + (value.name ?? "") + "," + (value.type ?? "")//this addition cost to performance
}
我也试过[ array].joined
,但这并没有什么不同
解决方案
首先,对于根本问题。为什么慢?根据我的经验,链接+
是导致大量编译时性能问题的最常见原因。这是因为+
有很多重载(我在 4.2 的 stdlib 中计算了 103 个)。Swift 不仅要证明它+
可以(String, String)
按照你的意愿使用。它必须证明没有其他可能的重载组合同样有效(如果有,它将是模棱两可的并且是错误的)。这不仅包括简单的情况,如 (Int, Int)。它还包括适用于 (String, String) 的复杂的基于协议的重载,但不如 (String, String) 精确,例如:
static func + <Other>(lhs: String, rhs: Other) -> String
where Other : RangeReplaceableCollection, Character == Other.Element
这需要很长时间,因为当您将一堆+
链接在一起时,它具有组合爆炸性。每个子表达式都必须根据它可能返回的所有内容重新考虑。
如何解决?首先,在这种情况下,我不会使用for
循环来逐个构建字符串。只是map
每个Offering
你想要的字符串,然后将它们连接在一起:
offeringsLabel.text = model?.offerings
.map { "\($0.name ?? ""),\($0.type ?? "")" }
.joined(separator: " | ")
这不仅会编译得更快,而且 IMO 更清楚你在做什么。它也不需要 a !
,这很好。(还有其他方法可以解决这个问题,但这是一个很好的副作用)。
也就是说,这也表明您的模型中可能存在问题。这是一个单独的问题,但我仍然会认真对待。任何时候你的代码看起来像:
optionalString ?? ""
您需要问,这真的应该是可选的吗?你真的对待零名称与空名称不同吗?如果不是,我相信name
andtype
应该只是String
而不是String?
,然后这变得更加简单。
offeringsLabel.text = model?.offerings
.map { "\($0.name),\($0.type)" }
.joined(separator: " | ")
此代码与您的代码略有不同。When model
is nil
,您的代码不会受到offeringsLabel
影响。我的代码清除了文本。这就提出了一个更深层次的问题:为什么在model
nil 时运行这段代码?为什么是model
可选的?您是否可以在数据中将其设为非可选,或者您是否应该guard let model = model else { return }
在此方法中使用更早的方法?
根据我的经验,导致 Swift 过于复杂的常见原因是过度使用 Optional。Optional 非常重要和强大,但你不应该使用它,除非你真正的意思是“这里没有任何价值是合法的,并且与'空'不同”。
推荐阅读
- php - opensearch自动发现链接未显示
- sql - 带有用户提示的 PL SQL 记录填充
- php - Yajra 数据表未在数据表中正确加载数据
- php - 给定流在 FPDI 中不可搜索
- excel - 索引超出范围必须小于或为负
- flutter - 添加 # 使用 Url_launcher 登录 tel uri
- css - 如何在 Firefox 中裁剪和对齐带有绝对单位的淡出 SVG 蒙版到右下角?
- sql-server - SQL 服务器负载平衡选项?
- angular - 从查看子组件中获取值(从子到父)
- paypal - Sandbox paypal php 付款发送到 null 未验证