# Deep recursion in deinit should not happen

**URL:** <https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987>\
**Category:** Discussion\
**Tags:** arc\
**Created:** [January 31, 2022, 5:37pm UTC](https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987 "2022-01-31T17:37:37Z")\
**Posts on this page:** 1\
**Showing post:** 43

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [January 21, 2023, 2:30pm UTC](https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987/43 "2023-01-21T14:30:49Z")

</div>

> [@sspringer](#):
>
> So your tests got much faster and does very well compared to C?

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)

```

> [@sspringer](#):
>
> I also checked [my original test case](https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987/1) and could not reproduce the previous error, so I suppose for this simple use case the "issue" is fixed 🙂

Yep, simple case fixed:

> **stackoverflow1 - direct recursion ✅**
>
> ```swift
> 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 💣**
>
> ```swift
> 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 💣**
>
> ```swift
> 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 💣**
>
> ```swift
> 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")
> }
> 
> ```

---

_[View the full topic](https://forums.swift.org/t/deep-recursion-in-deinit-should-not-happen/54987)._
