Xcode 6.3 (6D554n): [Swift] Performance issue with Set.first and Set.removeFirst()
| Originator: | janoschhildebrand | ||
| Number: | rdar://20293220 | Date Originated: | 25-Mar-2015 |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode 6.3 (6D554n) |
| Classification: | Performance | Reproducible: | Always |
Summary:
Accessing the first element in a Set appears to be extremely slow.
Take the following example:
import Cocoa
let size = 100000
func createSet() -> Set<Int> {
var set = Set<Int>()
for i in 0..<size {
set.insert(i)
}
return set
}
let insertStart = NSDate()
var set = createSet()
println("Insert: \(NSDate().timeIntervalSinceDate(insertStart))")
let removeFirstStart = NSDate()
while !set.isEmpty {
set.removeFirst()
}
println("RemoveFirst: \(NSDate().timeIntervalSinceDate(removeFirstStart))")
set = createSet()
let firstRemoveStart = NSDate()
while !set.isEmpty {
let first = set.first!
set.remove(first)
}
println("FirstRemove: \(NSDate().timeIntervalSinceDate(firstRemoveStart))")
set = createSet()
let removeLoopStart = NSDate()
for element in set {
set.remove(element)
}
println("RemoveLoop: \(NSDate().timeIntervalSinceDate(removeLoopStart))")
set = createSet()
let removeDirectStart = NSDate()
for i in 0..<size {
set.remove(i)
}
println("RemoveDirect: \(NSDate().timeIntervalSinceDate(removeDirectStart))")
This produces the following results on my machine (using -O):
Insert: 0.0234929919242859
RemoveFirst: 22.9310619831085
FirstRemove: 22.6014919877052
RemoveLoop: 0.0276380181312561
RemoveDirect: 0.0135889649391174
I would expect to achieve equal if not better performance using removeFirst() to remove members than using remove() but instead it is orders of magnitude slower...
Since a naive implementation of removeFirst() using Set.first and Set.remove seems to perform roughly equally bad but using Set.remove itself is fine I would expect Set.first to be the main culprit.
I have attached the example code as an Xcode project.
Forum thread: https://devforums.apple.com/thread/266229?tstart=0
Steps to Reproduce:
1. Open the attached project & run the target
2. Observe the resulting output
Expected Results:
I would expect Set.removeFirst() to perform equal to if not better Set.remove() when used to remove all the sets elements.
Actual Results:
Set.removeFirst() (and Set.remove(Set.first)) perform significantly worse.
Version:
Version 6.3 (6D554n)
Apple Swift version 1.2 (swiftlang-602.0.47.4 clang-602.0.48)
10.10.2 (14C1514)
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!