在SWIFT的ClosedRange中,contains方法似乎非常慢.

我在MacOS上创建了以下SWIFTplayground 进行测试:

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部分时发现了这一点

在一个真实的项目中,在开启优化的情况下发布构建(Optimize for speed [-O]),dt_b给了我356秒,比在操场上还差……

推荐答案

ClosedRange<Int>符合Collection,而您正在调用的contains是来自Collection:

func contains<C>(_ other: C) -> Bool where C : Collection, Self.Element == C.Element

这将判断self是否包含other中的所有元素.请注意,other是任意的Collection.此方法不是专门针对范围的.ClosedRange<Int>使用此方法的默认实现,因此范围没有特殊情况.默认实现遍历other的每个元素,并判断它们是否在self中.

换句话说,没有专门用于判断一个范围是否包含另一个范围的内置方法.有关您自己编写此类方法的其他方法,请参见this post.

Swift相关问答推荐

SwiftUI—如何识别单词并获取视觉中的位置

体积单位从夸脱转换为杯似乎关闭了

在Swift中,是否只有iOS版本超过15才能导入Swift包?

为什么枚举上的.allCases.forEach不是循环(继续和中断不起作用)?

正在接收具有不完整数据错误的URL请求

Swift 运算符中 inout 的行为

Swift 数组拆分成重叠的块

有没有一种方法可以访问封闭实例ObservableObject以从属性包装器中的任何位置调用objectWillChange.send()

为什么 SwiftUI 中 ForEach 的这个 Select 不起作用?

TextField 键入未完成

Pod lib lint 命令找不到 watchos 模拟器

动画偏移正在 destruct 按钮 SwiftUI

在主要参与者中启动分离任务和调用非隔离函数之间的区别

如何裁剪图像 3:4 ?迅速

为什么 Apple Scrumdinger Sample App 使用两个事实来源?

单击按钮后的计时器发布者初始化计时器

NSFontAttributeName 已更改为 String

协议扩展中的where self是什么

playground 导入:没有这样的模块Foo

如何在 SwiftUI Segmented Picker 中更改选定的段 colored颜色