我的应用程序中有一个视图控制器,用于调试目的以显示应用程序的一些内部结构(仅适用于本地 xcode 版本,应用程序商店版本没有此控制器)。
在此控制器中,我有一个标签,我想反映内部组件的状态(具体来说,我希望它显示该组件是启用还是禁用)。
我的问题:
.attributedText#1:将UILabel 的属性设置为与之前相同的值是否昂贵,或者我应该缓存旧值并仅在属性更改时设置该属性?
.text#2:(非归属)财产怎么样?
我目前正在使用以下代码:
// Schedule timer to update the control panel. (This is debug-only, so not worth
// the complexity of making this event-based)
Timer.scheduledTimer(withTimeInterval: 0.5,
repeats: true) { [weak self] timer in
DispatchQueue.main.async {
// Stop timer if we've been dealloced or are no longer being presented
guard let strongSelf = self,
strongSelf.isBeingPresented else
{
timer.invalidate()
return
}
// "Something Enabled / Disabled" label
let somethingIsEnabled = strongSelf.someDepenency.isEnabled
let somethingEnabledString = NSMutableAttributedString(string: "Something ")
somethingEnabledString.append(NSAttributedString(string: isEnabled ? "Enabled" : "Disabled",
attributes: isEnabled ? nil : [NSForegroundColorAttributeName: UIColor(xtHardcodedHexValue: "0xCD0408")]))
strongSelf.somethingEnabledLabel?.attributedText = somethingEnabledString
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在分享一些数字之前,我强烈建议不要执行此类过早的优化。考虑以下代码:
private func getAttributedString() -> NSMutableAttributedString{
let attributedString = NSMutableAttributedString(string: "Something ")
attributedString.append(NSAttributedString(string: "Enabled",
attributes: [NSForegroundColorAttributeName: UIColor(rgb: 0xCD0408)]))
return attributedString
}
//overwrites attributed text 100000 times
@IBAction func overwriteAttributedText(_ sender: Any) {
let timeBeforeAction = Date.init()
print ("Time taken to overwrite attributed text is ")
for _ in 1 ... 100000{
label.attributedText = getAttributedString()
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
//overwrites attributed text 100 times
@IBAction func cacheAttributedText(_ sender: Any) {
let timeBeforeAction = Date.init()
print ("Time taken to selectively overwrite attributed text is ")
for i in 1 ... 100000{
if i % 1000 == 0 {
label.attributedText = getAttributedString()
}
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
//overwrites text 100000 times
@IBAction func overWriteText(_ sender: Any) {
let defaultText = "Hello World"
let timeBeforeAction = Date.init()
print ("Time taken to overwrite text is ")
for _ in 1 ... 100000{
label.text = defaultText
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
Time taken to overwrite attributed text is 0.597925961017609
Time taken to selectively overwrite attributed text is 0.004891037940979
Time taken to overwrite text is 0.0462920069694519
Run Code Online (Sandbox Code Playgroud)
结果是不言而喻的,但如果需要这样的优化,我就留给你了。
虽然 7to4 在过早优化方面是正确的,但他使用的演示代码具有误导性。setter.attributedText本身实际上比 set 更快.text;创建属性字符串是瓶颈。这是他的代码的修改版本,其中包括预先缓存属性字符串的方法:
private func getAttributedString() -> NSMutableAttributedString{
let attributedString = NSMutableAttributedString(string: "Something ")
attributedString.append(NSAttributedString(string: "Enabled",
attributes: [NSAttributedStringKey.foregroundColor: UIColor.red]))
return attributedString
}
//overwrites attributed text 100000 times
@IBAction func overwriteAttributedText(_ sender: Any) {
let timeBeforeAction = Date.init()
print ("Time taken to overwrite attributed text is ")
for _ in 1 ... 100000{
label.attributedText = getAttributedString()
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
//overwrites attributed text 100000 times with a cached string
@IBAction func overwriteAttributedTextWithCachedString(_ sender: Any) {
let timeBeforeAction = Date.init()
let attributedString = getAttributedString()
print ("Time taken to overwrite attributed text with cached string is ")
for _ in 1 ... 100000{
label.attributedText = attributedString
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
//overwrites text 100000 times
@IBAction func overWriteText(_ sender: Any) {
let defaultText = "Hello World"
let timeBeforeAction = Date.init()
print ("Time taken to overwrite text is ")
for _ in 1 ... 100000{
label.text = defaultText
}
let timeAfterAction = Date.init()
let timeTaken = timeAfterAction.timeIntervalSince(timeBeforeAction)
print(timeTaken)
}
Run Code Online (Sandbox Code Playgroud)
结果:
Time taken to overwrite attributed text is
0.509455919265747
Time taken to overwrite attributed text with cached string is
0.0451710224151611
Time taken to overwrite text is
0.0634149312973022
Run Code Online (Sandbox Code Playgroud)
平均而言,.attributedText二传手本身比二传手快约30~40% .text。也就是说,请注意,在这实际上成为瓶颈之前,可能需要很多标签。还要记住(如果在某些疯狂的情况下)这是您的瓶颈,只有提前预先分配属性字符串,这种优化才有效。
| 归档时间: |
|
| 查看次数: |
1468 次 |
| 最近记录: |