Swift 中
contains
中的 ClosedRange
方法看起来非常慢。
我在 macOS 上创建以下 Swift Playground 进行测试:
import Foundation
func measure(fn: @escaping ()->Void) -> CFAbsoluteTime {
let startTime = CFAbsoluteTimeGetCurrent()
fn()
let endTime = CFAbsoluteTimeGetCurrent()
return endTime - startTime
}
let r1: ClosedRange<Int> = 1222450723...1308640992
let r2: ClosedRange<Int> = 41218238...462709950
let dt_a = measure { let _ = r1.lowerBound <= r2.lowerBound && r1.upperBound >= r2.upperBound }
let dt_b = measure { let _ = r1.contains(r2) }
contains
方法不应该简单地进行我在上面代码中为dt_a
所做的范围比较吗?
dt_a
给了我 95 微秒,而dt_b
给了我 326.9 秒(~5.45 分钟)这比预期慢了 340 万倍。
看起来它正在检查范围内的所有值,这是没有意义的。 这可能是 Swift 中的一个错误吗?或者这是预期的行为?
我正在使用 Xcode 15.0.1 (Swift 5)
(*) 注意:作为上下文,我在解决 2023 Advent of Code Day 5
第 2 部分时发现了这一点ClosedRange<Int>
符合 Collection
,并且您调用的 contains
是 Collection
中的 this方法:
func contains<C>(_ other: C) -> Bool where C : Collection, Self.Element == C.Element
这会检查
self
是否包含 other
中的所有元素。请注意,other
是任意的 Collection
。此方法并非专门用于范围。 ClosedRange<Int>
使用此方法的默认实现,因此范围没有特殊情况。默认实现会遍历 other
的每个元素并检查它们是否在 self
中。
换句话说,没有专门用于检查一个范围是否包含另一个范围的内置方法。请参阅这篇文章了解自己编写此类方法的其他方式。