Dear Devs,

I saw the WWDC 2016 video [Understanding Swift Performance][0] as well as some 
others regarding value types in swift of WWDC2015. I think there are a few 
ambiguities which make it hard both to decide which weapon to choose and to 
give proposition how to evolve this implementations to the better 
(swift-evolution).

Is there a place, where low-level decisions in the language are documented? Is 
there an adequate place/forum where we can ask questions regarding low-level 
implementations? It would be great if you add a (moderated) comment section to 
each of the WWDC videos, so that we can discuss the contents (with 
transcript-like links) as well as an errata section containing a list of 
Apple-Approved mistakes/ambiguities in a given video/talk.

# So, here come my questions

In the talk [Understanding Swift Performance][0] Kyle says, that value types 
are put stored in the stack and copied. He uses a point and a line which are 
both copied. Lateron Arnold uses a similar example with protocols. Then the 
Existential Container is used, which either uses the value buffer (for small 
values like `Point`) or allocates some memory on the heap and adds a pointer to 
this value (e.g. for a `Line`):

1. If I have an object (instance of a class) in a variable (or a container like 
an array) of a protocol type, will it be stored into an Existential Container, 
too? Or are reference types always stored as a reference (storing it in an 
Existential Container makes more sense to me).
2. If I use a variable of the concrete type (although it implements a 
protocol), will it always be copied (no matter its size) or does the compiler 
choose an existential container if it is greater than some given size (or 
perhaps even always, because it gives a good tradeoff?)
3. Then Arnold says that four existential containers pointing to the same value 
(greater than the value buffer) use 4 heap allocations. He proposes 
copy-on-write (using a local storage class), but **does he mean this should be 
implemented by hand or is this an optimization that the swift compiler does on 
its own?** The issue here is, that the switch between "swift subscript" for 
showing an abstraction of internals and real swift code that one should write 
is sometimes not clear. Doing this by hand has some clear disadvantages as this 
would add a reference to each usage of `Line` (and reference counting) even in 
the first examples of Kyle. Doing this as a compiler optimization would allow 
to use a struct in different scenarios and always the best tradeoff is used. 
Otherwise, I would perhaps even need to create two different types for 
different situations and choose it wisely. This would add a big burden on the 
developer.
4. If Arnold really means *manually* (see *3.*) and reference types are not 
stored in existential containers (see *1.*) the slides are wrong, because there 
a existential container is still used and the instance on the heap is named 
`Line` instead of `Line._storage`. So what is the case?
5. The implementations of `String` and `Array` seem to follow the copy-on-write 
strategy "manually", but I think they do that because this behavior is wanted 
even if the values would be copied automatically (if this is true, the answer 
for *3.* would be *manually*). Or am I wrong here?
6. Is the Value-Witness-Table a (kind of) dictionary for all values of a given 
value type (bigger than the value buffer), so that you do not store any value 
twice on the heap, but share the reference? If this is the case the answer of 
*3.* should be *automatically*. But then again, the "manual" implementation of 
`String` and `Array` (see *4.*) make no sense anymore, does it? Or are `Array` 
and `String` implemented only on the lower-level and the copy-on-write 
implementation is not visible in their Swift implementation?
7. If you want to have a reference-type (like `NSData`) with value semantics, 
then I need to implement my own copy-on-write of course, but if I want to have 
it only on the swift-value-type level the compiler should be able to do it all 
by itself, shouldn't it?

I read some [posts like this one][1] describing how Swift implements value 
types in a manner, that is conflicting with some of the things Kyle and Arnold 
said on WWDC 2016 (see above). Did Swift’s implementation change here between 
v2 and v3 or what do you think? The articles interpretation of the changes of 
the memory address (and the padding ints for the address struct; see the post) 
suggest, that always an existential container is used for structs (see *2.*) 
and copy-on-write is done automatically (see *3.*)…

It would be great, if someone could give me the answers to these questions :). 
Thanks in advance.

All the best
Johannes

[0]: https://developer.apple.com/videos/play/wwdc2016/416/
[1]: https://www.raywenderlich.com/112029/reference-value-types-in-swift-part-2

--
Dr. Johannes Neubauer
E-Mail: neuba...@kingsware.de
WWW   : http://www.kingsware.de

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to