Swift Struct vs. Class Performance
In the game that Michael and I are developing for our project derbe.cool we frequently use immutable structs that are copied and mutated multiple times for every user activity. That’s when I started to wonder what the performance difference is between copying a struct vs. a class.
A comparison of simple structs and classes using only value types or only referency types shows a huge difference.
import Foundation
let iterations = 10
// simple
struct SimpleStruct {
let value: UInt8
let anotherValue: UInt16
func setValue(_ value: UInt8) -> SimpleStruct {
return SimpleStruct(value: value, anotherValue: anotherValue)
}
}
class SimpleClass {
let value: UInt8
let anotherValue: UInt16
init(value: UInt8, anotherValue: UInt16) {
self.value = value
self.anotherValue = anotherValue
}
func setValue(_ value: UInt8) -> SimpleClass {
return SimpleClass(value: value, anotherValue: anotherValue)
}
}
let structStartDate = Date()
var aStruct = SimpleStruct(value: 1, anotherValue: 2)
for v in 0..<iterations {
aStruct = aStruct.setValue(UInt8(v % 255))
}
let structDuration = Date().timeIntervalSince(structStartDate)
print("simple struct \(structDuration)")
let classesStartDate = Date()
var aClass = SimpleClass(value: 1, anotherValue: 2)
for v in 0..<iterations {
aClass = aClass.setValue(UInt8(v % 255))
}
let classDuration = Date().timeIntervalSince(structStartDate)
print("simple class \(classDuration)")
// moreComplex
struct ComplexStruct {
let values: [UInt8]
func setFirstValue(_ value: UInt8) -> ComplexStruct {
var newValues = values
newValues[0] = value
return ComplexStruct(values: newValues)
}
}
class ComplexClass {
let values: [UInt8]
init(values: [UInt8]) {
self.values = values
}
func setFirstValue(_ value: UInt8) -> ComplexClass {
var newValues = values
newValues[0] = value
return ComplexClass(values: newValues)
}
}
let complexStructStartDate = Date()
var complexStruct = ComplexStruct(values: [1])
for v in 0..<iterations {
complexStruct = complexStruct.setFirstValue(UInt8(v % 255))
}
let complexStructDuration = Date().timeIntervalSince(complexStructStartDate)
print("complex struct \(structDuration)")
let complexClassesStartDate = Date()
var complexClass = ComplexClass(values: [1])
for v in 0..<iterations {
complexClass = complexClass.setFirstValue(UInt8(v % 255))
}
let complexClassDuration = Date().timeIntervalSince(complexClassesStartDate)
print("complex class \(classDuration)")
simple struct 0.0083010196685791
simple class 0.0205469131469727
complex struct 0.0083010196685791
complex class 0.0205469131469727