Relative figures for swift are about the same. All tests got proportionally faster on the newer hardware. Obj-C becomes slower. Putting the old and new results together:
Old (x86 computer of 2016):
C alloc: 13.66, dealloc: 13.96, total: 27.63
Swift unsafe alloc: 14.85, dealloc: 14.12, total: 28.98 (5% slower than C)
Obj-C MRC alloc: 15.84, dealloc: 18.27, total: 34.11 (23% slower than C)
Swift (ARC) alloc: 20.43, dealloc: 26.36, total: 46.79 (69% slower than C)
Obj-C ARC alloc: 21.27, dealloc: 32.58, total: 53.86 (95% slower than C)
New (M1 Pro computer of 2021):
C alloc: 3.21, dealloc: 4.16, total: 7.37
swift unsafe alloc: 3.68, dealloc: 3.99, total: 7.68 (4% slower than C)
objc MRC alloc: 4.69, dealloc: 5.18, total: 9.87 (34% slower than C)
swift (ARC) alloc: 4.22, dealloc: 8.12, total: 12.34 (67% slower than C)
objc ARC alloc: 5.84, dealloc: 14.47, total: 20.31 (176% slower than C)
Yep, simple case fixed:
stackoverflow1 - direct recursion ✅
class Node1 {
var next: Node1?
init(next: Node1?) {
self.next = next
}
}
func stackOverflow1() {
var top: Node1?
print("alloc")
for _ in 0 ..< 100000 {
top = Node1(next: top)
}
print("free!!")
top = nil
print("done!!")
}
More general cases not:
stackOverflow2 - indirect recursion 💣
class NodeA {
var next: NodeB?
init(next: NodeB?) {
self.next = next
}
}
class NodeB {
var next: NodeA?
init(next: NodeA?) {
self.next = next
}
}
func stackOverflow2() {
var top: NodeA?
print("alloc")
for _ in 0 ..< 100000 {
top = NodeA(next: NodeB(next: top))
}
print("free")
top = nil // crash here
print("done")
}
stackOverflow3 - children in array 💣
class Node3 {
var children: [Node3]
init(children: [Node3]) {
self.children = children
}
}
func stackOverflow3() {
var top = Node3(children: [])
print("alloc")
for _ in 0 ..< 100000 {
top = Node3(children: [top])
}
print("free")
top = Node3(children: []) // crash
print("done")
}
stackOverflow4 - indirect enum 💣
indirect enum Node4 {
case last(payload: Int)
case notLast(payload: Int, next: Node4)
init(payload: Int) {
self = .last(payload: payload)
}
init(payload: Int, next: Node4) {
self = .notLast(payload: payload, next: next)
}
}
func stackOverflow4() {
var top = Node4(payload: 0)
print("alloc")
for i in 1 ..< 100000 {
top = Node4(payload: i, next: top)
}
print("free")
top = Node4(payload: 0) // crash
print("done")
}