mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +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 half = size / 2
|
||||||
let quarter = size / 4
|
let quarter = size / 4
|
||||||
|
|
||||||
|
// Construction of empty sets.
|
||||||
|
let setE: Set<Int> = []
|
||||||
|
let setOE: Set<Box<Int>> = []
|
||||||
|
|
||||||
// Construction kit for sets with 25% overlap
|
// Construction kit for sets with 25% overlap
|
||||||
let setAB = Set(0 ..< size) // 0 ..< 400
|
let setAB = Set(0 ..< size) // 0 ..< 400
|
||||||
let setCD = Set(size ..< 2 * size) // 400 ..< 800
|
let setCD = Set(size ..< 2 * size) // 400 ..< 800
|
||||||
@@ -53,6 +57,11 @@ let setQ: Set<Int> = {
|
|||||||
|
|
||||||
public let SetTests = [
|
public let SetTests = [
|
||||||
// Mnemonic: number after name is percentage of common elements in input sets.
|
// 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(
|
BenchmarkInfo(
|
||||||
name: "SetIsSubsetInt0",
|
name: "SetIsSubsetInt0",
|
||||||
runFunction: { n in run_SetIsSubsetInt(setAB, setCD, false, 5000 * n) },
|
runFunction: { n in run_SetIsSubsetInt(setAB, setCD, false, 5000 * n) },
|
||||||
@@ -84,6 +93,47 @@ public let SetTests = [
|
|||||||
tags: [.validation, .api, .Set],
|
tags: [.validation, .api, .Set],
|
||||||
setUpFunction: { blackHole([setP, setQ]) }),
|
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(
|
BenchmarkInfo(
|
||||||
name: "SetSymmetricDifferenceInt0",
|
name: "SetSymmetricDifferenceInt0",
|
||||||
runFunction: { n in run_SetSymmetricDifferenceInt(setAB, setCD, countABCD, 10 * n) },
|
runFunction: { n in run_SetSymmetricDifferenceInt(setAB, setCD, countABCD, 10 * n) },
|
||||||
@@ -177,6 +227,16 @@ public let SetTests = [
|
|||||||
tags: [.validation, .api, .Set],
|
tags: [.validation, .api, .Set],
|
||||||
setUpFunction: { blackHole([setP, setQ]) }),
|
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(
|
BenchmarkInfo(
|
||||||
name: "SetSubtractingInt0",
|
name: "SetSubtractingInt0",
|
||||||
runFunction: { n in run_SetSubtractingInt(setAB, setCD, countAB, 10 * n) },
|
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 {
|
class Box<T : Hashable> : Hashable {
|
||||||
var value: T
|
var value: T
|
||||||
|
|
||||||
@@ -371,3 +443,15 @@ func run_SetSubtractingBox(
|
|||||||
CheckResults(and.count == r)
|
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
|
@inlinable
|
||||||
public func isSubset<S: Sequence>(of possibleSuperset: S) -> Bool
|
public func isSubset<S: Sequence>(of possibleSuperset: S) -> Bool
|
||||||
where S.Element == Element {
|
where S.Element == Element {
|
||||||
// FIXME(performance): isEmpty fast path, here and elsewhere.
|
guard !isEmpty else { return true }
|
||||||
|
|
||||||
let other = Set(possibleSuperset)
|
let other = Set(possibleSuperset)
|
||||||
return isSubset(of: other)
|
return isSubset(of: other)
|
||||||
}
|
}
|
||||||
@@ -763,10 +764,12 @@ extension Set: SetAlgebra {
|
|||||||
@inlinable
|
@inlinable
|
||||||
public func isSuperset<S: Sequence>(of possibleSubset: __owned S) -> Bool
|
public func isSuperset<S: Sequence>(of possibleSubset: __owned S) -> Bool
|
||||||
where S.Element == Element {
|
where S.Element == Element {
|
||||||
// FIXME(performance): Don't build a set; just ask if every element is in
|
for member in possibleSubset {
|
||||||
// `self`.
|
if !contains(member) {
|
||||||
let other = Set(possibleSubset)
|
return false
|
||||||
return other.isSubset(of: self)
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a Boolean value that indicates whether the set is a strict
|
/// Returns a Boolean value that indicates whether the set is a strict
|
||||||
@@ -811,9 +814,7 @@ extension Set: SetAlgebra {
|
|||||||
@inlinable
|
@inlinable
|
||||||
public func isDisjoint<S: Sequence>(with other: S) -> Bool
|
public func isDisjoint<S: Sequence>(with other: S) -> Bool
|
||||||
where S.Element == Element {
|
where S.Element == Element {
|
||||||
// FIXME(performance): Don't need to build a set.
|
return _isDisjoint(with: other)
|
||||||
let otherSet = Set(other)
|
|
||||||
return isDisjoint(with: otherSet)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new set with the elements of both this set and the given
|
/// Returns a new set with the elements of both this set and the given
|
||||||
@@ -920,6 +921,10 @@ extension Set: SetAlgebra {
|
|||||||
@inlinable
|
@inlinable
|
||||||
internal mutating func _subtract<S: Sequence>(_ other: S)
|
internal mutating func _subtract<S: Sequence>(_ other: S)
|
||||||
where S.Element == Element {
|
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 {
|
for item in other {
|
||||||
remove(item)
|
remove(item)
|
||||||
}
|
}
|
||||||
@@ -1121,8 +1126,16 @@ extension Set {
|
|||||||
/// otherwise, `false`.
|
/// otherwise, `false`.
|
||||||
@inlinable
|
@inlinable
|
||||||
public func isDisjoint(with other: Set<Element>) -> Bool {
|
public func isDisjoint(with other: Set<Element>) -> Bool {
|
||||||
for member in self {
|
return _isDisjoint(with: other)
|
||||||
if other.contains(member) {
|
}
|
||||||
|
|
||||||
|
@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
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user