// test.swift
// A little cmd line app that demonstrates Set(arrayOfStrings) being
// very slow for a particular arrayOfStrings.
// Compiled using: swiftc -O test.swift
// Tested with
// swiftc --version
// Apple Swift version 2.2 (swiftlang-703.0.17.2 clang-703.0.26)
// Target: x86_64-apple-macosx10.9
// and
// swiftc --version
// Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
// Target: x86_64-apple-darwin15.3.0
// Both produces the results shown by the comments.

import QuartzCore // Need this for timing using CACurrentTimeMillis().

func swapCase(s: String) -> String {
    return s.characters.map {
        let charAsString = String($0)
        switch charAsString {
        case charAsString.uppercaseString: return charAsString.lowercaseString
        case charAsString.lowercaseString: return charAsString.uppercaseString
        default: return charAsString

func test(strings: [String]) {
    let t0 = CACurrentMediaTime()
    let set = Set(strings)
    let t1 = CACurrentMediaTime()
    print("Created set of", set.count, "strings in", t1 - t0, "seconds.")

// Download http://sloppyfocus.com/strings.zip, unzip and set the correct path here:
let path = "/Users/jens/strings.txt" 

do {
    let strings = try String.init(contentsOfFile: path).componentsSeparatedByString("\n")
    print("Loaded", strings.count, "strings into an array of strings.") // Prints: Loaded 88379 strings.
    let caseSwappedStrings = strings.map(swapCase)
    test(caseSwappedStrings) // Prints (on my machine): Created set of 88379 strings in 0.066170030986541 seconds.
    test(strings)            // Prints (on my machine): Created set of 88379 strings in 9.50514279599884 seconds.
catch let e { fatalError(String(e)) }

// So it takes ~ 143 times longer to make Set(strings) than to make Set(caseSwappedStrings).
// The strings in strings.txt are not strange in any way, they all match ^[a-zA-Z ]+$.
// Note that eg inserting dashes between every character will also make Set(strings) faster,
// so it's not case-swapping per se that makes it faster/non-slow, it's rather that the particular strings in
// strings.txt, for some reason, makes Set(strings) very slow.
// I have not been able to reproduce the slow behaviour for other string-arrays, I've tried generating
// (equally many and unique) random [a-zA-Z ]+ strings, tried sorting them in various ways, etc.
// Any ideas? @bitCycle