Running this on my MBP with 10 as the parameter: 
https://gist.github.com/zneak/ae33bb970a08632cfb2925e2049f9e7a 
<https://gist.github.com/zneak/ae33bb970a08632cfb2925e2049f9e7a> 

I get a runtime of about 10 seconds, 45% of which is spent in retain/release 
calls according to Instruments (!!), and at least half of that from Expr.count. 
Looking at the IR, Swift generously sprinkles retain/release calls through the 
outlined copy method:

`self` is retained at the beginning of `count`
The values that you get out of destructuring are retained
Of course, when you get `count` on these, they are retained again

Of course, Expr.count cannot modify itself or its subexpressions because the 
functions are not mutating; in fact, no function in that program can mutate an 
enum case. Why, then, is Swift retaining/releasing `self` and the values 
obtained from destructured patterns? They can't go away. Shouldn't we be 
getting guaranteed references instead of owning references?

That seems to hit pattern-matching-heavy programs with indirect cases pretty 
hard, and it's pretty frustrating because that seems to be about the nicest way 
to write this program, and there's no workaround from the developer's 
perspective. I don't think that this is a fatal flaw of refcounting, but unless 
I'm missing something, that's sub-par behavior.

Félix
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to