【问题标题】:Why is it getting slower and slower each time I call the formatted() method of the Decimal type in Swift?为什么在Swift中每次调用Decimal类型的formatted()方法都会越来越慢?
【发布时间】:2023-01-12 22:47:02
【问题描述】:

我需要将整数分成 3 位数,并查看了 Decimal 类型的 formatted() 方法。
为随机整数调用类型为 Decimalformatted() 方法 100,000 次会逐渐降低性能。
我想知道为什么会这样。

import Foundation

/// https://stackoverflow.com/a/56381954
func calculateTime(block : (() -> Void)) {
  let start = DispatchTime.now()
  block()
  let end = DispatchTime.now()
  let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
  let timeInterval = Double(nanoTime) / 1_000_000_000
  print("Time: \(timeInterval) seconds")
}

calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
calculateTime { for _ in 0...100_000 { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } }
Time: 0.9492465 seconds
Time: 3.29213125 seconds
Time: 7.988363667 seconds
Time: 15.165178292 seconds
Time: 17.305036583 seconds
Time: 25.0114935 seconds
Time: 35.746310417 seconds
Time: 47.024551125 seconds

【问题讨论】:

标签: swift


【解决方案1】:

这是一个 Heisenbug:您正在通过使用测试工具占用内存来导致自己减速。将您的测试线更改为:

calculateTime { for _ in 0...100_000 { autoreleasepool { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } } }
calculateTime { for _ in 0...100_000 { autoreleasepool { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } } }
calculateTime { for _ in 0...100_000 { autoreleasepool { _ = Decimal(Int.random(in: 0...Int.max)).formatted() } } }
// ... and so on

【讨论】:

    【解决方案2】:

    虽然 matt 和 Martin R 是正确的,但他们实际上并没有指出罪魁祸首。当您使用“内存对象”调试器时,当函数正在执行时,您会看到这个非常有趣的图表:

    因此,formatted() 函数会导致大量分配,主要是NSAutoLocale 类型的对象。

    这暗示了进一步的问题:因为评估语言环境需要访问文件在实际读取区域设置的地方,您也可能会遇到非常慢的性能。

    所以,如果你也想加快速度,你应该明确地使用一个预先配置的语言环境对象,你分配一次,而且只分配一次,然后你将它用作参数来格式化字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      相关资源
      最近更新 更多