While profiling my app, one of the top functions is OpCode.__derived_enum_equals(::) for the enum with associated values below. I was surprised to discover a 5.9x performance difference in the synthesized function depending on parameter order.
Running the code below in a command-line app, compiled optimized with safety checks disabled on my M1 mini gives:
.plus == x returns 1000000000 in 0.32s
x == .plus returns 1000000000 in 1.88s
The asymmetry is dependent on the number of cases in the enum. Remove one case and then both parameter orders are fast.
import Foundation
enum OpCode : Equatable {
case number(Double, String = "")
case atomic(String)
case string(String)
case matrix(_ rows: Int, _ cols: Int)
case prompt, plus, minus, times, divide, power, list, equal, notequal, less, leq, greater, geq, elementof,
sin, cos, tan, csc, sec, cot, asin, acos, atan, acsc, asec, acot,
sinh, cosh, tanh, csch, sech, coth, asinh, acosh, atanh, acsch, asech, acoth,
index, function, substitution, factorial, superscriptT, plusorminus, minusorplus, sgn, log, sqrt,
grad, div, curl, lap, optotal, oppartial, sum, product, id, abs, overline, sn, choice, interval,
dot, cross, floor, ceil, ln, exp, arg, real, imag, Re, Im, prime, hat, besselj, conditional, piecewise,
integral, mod, min, max, clamp, Count, Sum, Mean, StdDev, slider, set, Transpose, Trace, Det,
Rotate, Interpolate, And, Or, Not, Inf, Sup, lim, partial, total, dataIndex, atan2, square, powfrac,
piecewiseConditional, labeledPiecewise(Int)
}
func time(_ description: String, function: () -> Int) {
let iterations = 1000000000
let start = DispatchTime.now().uptimeNanoseconds
var sum = 0
for _ in 1 ... iterations { sum += function() }
let end = DispatchTime.now().uptimeNanoseconds
print("\(description) returns \(sum) in \(String(format: "%.2f", Double(end - start)/1.0e9))s")
}
var x = OpCode.string("x")
time(".plus == x") { .plus == x ? 0 : 1}
time("x == .plus") { x == .plus ? 0 : 1}
Reported in FB9775661
Any suggestions for a work-around other than writing func == out the long way?