为什么ClosedRange<Int>.contains比预期慢了340万倍?

问题描述 投票:0回答:1

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 部分时发现了这一点
swift performance range
1个回答
1
投票

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
中。

换句话说,没有专门用于检查一个范围是否包含另一个范围的内置方法。请参阅这篇文章了解自己编写此类方法的其他方式。

© www.soinside.com 2019 - 2024. All rights reserved.