mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[stdlib] Resolving some FIXME comments on Set type. (#20631)
* Fixing some fixmes on stdlib Set * Adding @inline attr * Fixing spaces * Adding isEmpty as fast path in other places where is possible. * Quotes on variable name on comment. * Update stdlib/public/core/Set.swift Co-Authored-By: LucianoPAlmeida <passos.luciano@outlook.com> * Adding benchmark for isDisjoint Set method * Adding empty sets to benchmark * Fixing the factor on benchmarks and naming warnings for empty 5 words
This commit is contained in:
committed by
Nate Cook
parent
5c7fd17c3c
commit
2bc5623bdf
@@ -16,6 +16,10 @@ let size = 400
|
||||
let half = size / 2
|
||||
let quarter = size / 4
|
||||
|
||||
// Construction of empty sets.
|
||||
let setE: Set<Int> = []
|
||||
let setOE: Set<Box<Int>> = []
|
||||
|
||||
// Construction kit for sets with 25% overlap
|
||||
let setAB = Set(0 ..< size) // 0 ..< 400
|
||||
let setCD = Set(size ..< 2 * size) // 400 ..< 800
|
||||
@@ -53,6 +57,11 @@ let setQ: Set<Int> = {
|
||||
|
||||
public let SetTests = [
|
||||
// Mnemonic: number after name is percentage of common elements in input sets.
|
||||
BenchmarkInfo(
|
||||
name: "Set.Empty.IsSubsetInt0",
|
||||
runFunction: { n in run_SetIsSubsetInt(setE, setAB, true, 5000 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setE, setAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsSubsetInt0",
|
||||
runFunction: { n in run_SetIsSubsetInt(setAB, setCD, false, 5000 * n) },
|
||||
@@ -84,6 +93,47 @@ public let SetTests = [
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setP, setQ]) }),
|
||||
|
||||
BenchmarkInfo(
|
||||
name: "Set.Empty.IsDisjointInt0",
|
||||
runFunction: { n in run_SetIsDisjointInt(setE, setAB, true, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setE, setAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "Set.Empty.IsDisjointBox0",
|
||||
runFunction: { n in run_SetIsDisjointBox(setOE, setOAB, true, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setOE, setOAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointInt0",
|
||||
runFunction: { n in run_SetIsDisjointInt(setAB, setCD, true, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setAB, setCD]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointBox0",
|
||||
runFunction: { n in run_SetIsDisjointBox(setOAB, setOCD, true, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setOAB, setOCD]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointInt25",
|
||||
runFunction: { n in run_SetIsDisjointInt(setB, setAB, false, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setB, setAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointBox25",
|
||||
runFunction: { n in run_SetIsDisjointBox(setOB, setOAB, false, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setOB, setOAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointInt50",
|
||||
runFunction: { n in run_SetIsDisjointInt(setY, setXY, false, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setY, setXY]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetIsDisjointInt100",
|
||||
runFunction: { n in run_SetIsDisjointInt(setP, setQ, false, 50 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setP, setQ]) }),
|
||||
|
||||
BenchmarkInfo(
|
||||
name: "SetSymmetricDifferenceInt0",
|
||||
runFunction: { n in run_SetSymmetricDifferenceInt(setAB, setCD, countABCD, 10 * n) },
|
||||
@@ -177,6 +227,16 @@ public let SetTests = [
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setP, setQ]) }),
|
||||
|
||||
BenchmarkInfo(
|
||||
name: "Set.Empty.SubtractingInt0",
|
||||
runFunction: { n in run_SetSubtractingInt(setE, setAB, 0, 10 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setE, setAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "Set.Empty.SubtractingBox0",
|
||||
runFunction: { n in run_SetSubtractingBox(setOE, setOAB, 0, 10 * n) },
|
||||
tags: [.validation, .api, .Set],
|
||||
setUpFunction: { blackHole([setOE, setOAB]) }),
|
||||
BenchmarkInfo(
|
||||
name: "SetSubtractingInt0",
|
||||
runFunction: { n in run_SetSubtractingInt(setAB, setCD, countAB, 10 * n) },
|
||||
@@ -296,6 +356,18 @@ public func run_SetSubtractingInt(
|
||||
}
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func run_SetIsDisjointInt(
|
||||
_ a: Set<Int>,
|
||||
_ b: Set<Int>,
|
||||
_ r: Bool,
|
||||
_ n: Int) {
|
||||
for _ in 0 ..< n {
|
||||
let isDisjoint = a.isDisjoint(with: identity(b))
|
||||
CheckResults(isDisjoint == r)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<T : Hashable> : Hashable {
|
||||
var value: T
|
||||
|
||||
@@ -371,3 +443,15 @@ func run_SetSubtractingBox(
|
||||
CheckResults(and.count == r)
|
||||
}
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
func run_SetIsDisjointBox(
|
||||
_ a: Set<Box<Int>>,
|
||||
_ b: Set<Box<Int>>,
|
||||
_ r: Bool,
|
||||
_ n: Int) {
|
||||
for _ in 0 ..< n {
|
||||
let isDisjoint = a.isDisjoint(with: identity(b))
|
||||
CheckResults(isDisjoint == r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,7 +712,8 @@ extension Set: SetAlgebra {
|
||||
@inlinable
|
||||
public func isSubset<S: Sequence>(of possibleSuperset: S) -> Bool
|
||||
where S.Element == Element {
|
||||
// FIXME(performance): isEmpty fast path, here and elsewhere.
|
||||
guard !isEmpty else { return true }
|
||||
|
||||
let other = Set(possibleSuperset)
|
||||
return isSubset(of: other)
|
||||
}
|
||||
@@ -763,10 +764,12 @@ extension Set: SetAlgebra {
|
||||
@inlinable
|
||||
public func isSuperset<S: Sequence>(of possibleSubset: __owned S) -> Bool
|
||||
where S.Element == Element {
|
||||
// FIXME(performance): Don't build a set; just ask if every element is in
|
||||
// `self`.
|
||||
let other = Set(possibleSubset)
|
||||
return other.isSubset(of: self)
|
||||
for member in possibleSubset {
|
||||
if !contains(member) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/// Returns a Boolean value that indicates whether the set is a strict
|
||||
@@ -811,9 +814,7 @@ extension Set: SetAlgebra {
|
||||
@inlinable
|
||||
public func isDisjoint<S: Sequence>(with other: S) -> Bool
|
||||
where S.Element == Element {
|
||||
// FIXME(performance): Don't need to build a set.
|
||||
let otherSet = Set(other)
|
||||
return isDisjoint(with: otherSet)
|
||||
return _isDisjoint(with: other)
|
||||
}
|
||||
|
||||
/// Returns a new set with the elements of both this set and the given
|
||||
@@ -920,6 +921,10 @@ extension Set: SetAlgebra {
|
||||
@inlinable
|
||||
internal mutating func _subtract<S: Sequence>(_ other: S)
|
||||
where S.Element == Element {
|
||||
// If self is empty we don't need to iterate over `other` because there's
|
||||
// nothing to remove on self.
|
||||
guard !isEmpty else { return }
|
||||
|
||||
for item in other {
|
||||
remove(item)
|
||||
}
|
||||
@@ -1121,8 +1126,16 @@ extension Set {
|
||||
/// otherwise, `false`.
|
||||
@inlinable
|
||||
public func isDisjoint(with other: Set<Element>) -> Bool {
|
||||
for member in self {
|
||||
if other.contains(member) {
|
||||
return _isDisjoint(with: other)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
internal func _isDisjoint<S: Sequence>(with other: S) -> Bool
|
||||
where S.Element == Element {
|
||||
guard !isEmpty else { return true }
|
||||
|
||||
for member in other {
|
||||
if contains(member) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user