My Swift app iterates over two Array<String>
and compares their elements.
Something very strange is going on. I have the impression the compiler is doing some optimizations that I cannot understand: commenting out the print statement in MyInterface.run()
improves the runtime from about 10 seconds to below 0.5 seconds, and that print statement is executed only once at the end of the program. Even commenting out the if
above it has the same effect.
I'm running the app in Xcode Instruments. When debugging it in Xcode, there is no difference when commenting out any of those two lines.
Instruments shows that most of the time is spent in protocol witness for Collection.subscript.read in conformance [A]
, Array.subscript.read
and similar, which in turn call different malloc
, initialize
, free
and release
methods.
What's the problem with this code?
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let x = Array(repeating: "adsf", count: 100000)
let y = Array(repeating: "adsf", count: 100000)
let diff = MyInterface(x: x, y: y)
diff.run()
}
}
class MyInterface<List: RandomAccessCollection & MutableCollection> where List.Element: Comparable, List.Index == Int {
private let algorithm: Algorithm<List>
init(x: List, y: List) {
algorithm = AlgorithmSubclass(x: x, y: y)
}
func run() {
algorithm.run()
if (0..<1).randomElement() == 0 {
print(algorithm.x.count) // commenting out this line, or the if above, makes the program 20x faster
}
}
}
class Algorithm<List: RandomAccessCollection> where List.Element: Equatable, List.Index == Int {
var x: List
var y: List
init(x: List, y: List) {
self.x = x
self.y = y
}
func run() {
}
}
class AlgorithmSubclass<List: RandomAccessCollection>: Algorithm<List> where List.Element: Equatable, List.Index == Int {
override func run() {
var count = 0
for _ in 0..<1000 {
for i in 0..<min(x.endIndex, y.endIndex) {
if x[i] == y[i] {
count += 1
}
}
}
let alert = NSAlert()
alert.messageText = "\(count)"
alert.runModal()
}
}