@@ -544,6 +544,38 @@ protocols as class-only protocols to get better runtime performance.
544
544
545
545
.. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
546
546
547
+ The Cost of Let/Var when Captured by Escaping Closures
548
+ ======================================================
549
+
550
+ While one may think that the distinction in between let/var is just
551
+ about language semantics, there are also performance
552
+ considerations. Remember that any time one creates a binding for a
553
+ closure, one is forcing the compiler to emit an escaping closure,
554
+ e.x.:
555
+
556
+ ::
557
+
558
+ let f: () -> () = { ... } // Escaping closure
559
+ // Contrasted with:
560
+ ({ ... })() // Non Escaping closure
561
+ x.map { ... } // Non Escaping closure
562
+
563
+ When a var is captured by an escaping closure, the compiler must
564
+ allocate a heap box to store the var so that both the closure
565
+ creator/closure can read/write to the value. This even includes
566
+ situations where the underlying type of the captured binding is
567
+ trivial! In contrast, when captured a `let ` is captured by value. As
568
+ such, the compiler stores a copy of the value directly into the
569
+ closure's storage without needing a box.
570
+
571
+ Advice: Pass var as an `inout ` if closure not actually escaping
572
+ ---------------------------------------------------------------
573
+
574
+ If one is using an escaping closure for expressivity purposes, but is
575
+ actually using a closure locally, pass vars as inout parameters
576
+ instead of by using captures. The inout will ensure that a heap box is
577
+ not allocated for the variables and avoid any retain/release traffic
578
+ from the heap box being passed around.
547
579
548
580
Unsupported Optimization Attributes
549
581
===================================
0 commit comments