// V1
enum VaccineCodeSet: String {
case covidModerna = "207"
case covidBioNTech = "208"
case covidAstraZeneca = "210"
case covidNovax = "211"
case covidJohnson = "212"
case covidValneva = "213"
case hepatitesB = "45"
case whoopingCough = "11"
case measles = "05"
case mumps = "07"
case rubella = "06"
case chickenpox = "21"
case tbe = "77"
case hepatitesA = "85"
case yellowFever = "184"
static var allCases: Set<String> = [
Self.covidModerna.rawValue,
Self.covidBioNTech.rawValue,
Self.covidAstraZeneca.rawValue,
Self.covidNovax.rawValue,
Self.covidJohnson.rawValue,
Self.covidValneva.rawValue,
Self.hepatitesB.rawValue,
Self.whoopingCough.rawValue,
Self.measles.rawValue,
Self.mumps.rawValue,
Self.rubella.rawValue,
Self.chickenpox.rawValue,
Self.tbe.rawValue,
Self.hepatitesA.rawValue,
Self.yellowFever.rawValue
]
}
printTimeElapsedWhenRunningCode(title: "VaccineCodeSet") {
if VaccineCodeSet.allCases.contains("184") {
true
}
}
// Time elapsed to check: 0.006421875 s.
// V2
enum VaccineCodeCaseIterable: String, CaseIterable {
case covidModerna = "207"
case covidBioNTech = "208"
case covidAstraZeneca = "210"
case covidNovax = "211"
case covidJohnson = "212"
case covidValneva = "213"
case hepatitesB = "45"
case whoopingCough = "11"
case measles = "05"
case mumps = "07"
case rubella = "06"
case chickenpox = "21"
case tbe = "77"
case hepatitesA = "85"
case yellowFever = "184"
}
printTimeElapsedWhenRunningCode(title: "Array") {
if let code = VaccineCodeCaseIterable(rawValue: "184"),
IllnessCodeCaseIterable.allCases.contains(code) {
true
}
}
// Time elapsed to check:: 0.005916875 s.
I guess this is a typo and should be VaccineCodeSet.allCases.contains.
Let's see. In the first case you have a Set of strings, in the second case you have an Array of enumeration values (note that it is not an array of strings, it's more like array of integers). Worth noting that the number of elements is small. And that the measured time difference is also small. And the strings are tiny – will be stored inline string structs without being allocated on heap. Set lookup is one hash calculation plus O(1) element comparisons, Array lookup is O(n) element comparisons. The combination of these factors make Array version the winner in this test: it's faster to compare 15 ints then to do a hash calculation of a short inline stored string and then do one (or few) short string comparisons. Under different conditions (e.g. a larger number of elements) set would be a winner. OTOH, if you had a longer heap allocated strings the number of elements for the set version to be a winner would be higher.
Users are allowed to customize CaseIterable conformance, even if it’s not recommended. BUT the compiler could still do the optimization if it knows the conformance was synthesized. BUT it would be silly to add an optimization (and thus add compile time) for something that people are very unlikely to write in practice.
V2 does have one more bit of work to do: going from a String to an enum case. But that can be optimized (in the init(rawValue:) implementation) because the compiler knows the full set of possible valid strings, so it ends up faster than the hash lookup. (In fact, since all the strings are short, it can even be done as an integer switch, treating the string contents as a multi-byte integer after checking the length. I didn’t look to see if this is what actually gets generated, though.)