Sorry, not sure how I missed that 😑.
> On Aug 4, 2017, at 3:16 PM, Félix Cloutier <felixclout...@icloud.com> wrote: > > >> Le 4 août 2017 à 11:39, Robert Bennett <rltbenn...@icloud.com> a écrit : >> >>> That's not a concern with the `let` case that Robert brought up, since you >>> can't mutate a `let` array at all. >>> >>> The big thing is that unconstrained escape analysis is uncomputable. Since >>> Swift array storage is COW, any function that receives the array as a >>> parameter is allowed to take a reference on its storage. If the storage >>> lives on the stack and that reference outlives the stack frame, you've got >>> a problem. It's the same problem that motivated @escaping for closures. >>> >>> You could allow storage to be on the stack by forcing user to make a >>> pessimistic copy, which is possibly not an improvement. >> >> >> Good point. If this is only problematic when multiple threads are accessing >> an array, then it could still be worthwhile if all accesses are (provably) >> on the thread that created the array. > > To be clear, it's a problem independently of multi-threading. `func foo() -> > [Int] { return [1, 2, 3] }` is the most basic representation of it: you can't > store the array in the stack frame if you return it. (To be fair, that one > would be caught by escape analysis of any quality.) `func foo() { bar([1, 2, > 3, 4]) }` is another example: if you don't know what `bar` does with the > array, you can't store it on the stack because it might pass it to an object > that lives on the heap and outlives `foo`, for instance. @escaping solves > that problem for closures by specifically annotating parameters when the > assigned closure could still be referenced after the called function returns. > >> And pessimistic copying might still be worth it for arrays below a certain >> size — for instance, copying an Array<Int> of length 1 (and recall that the >> array in question is a constant so its size is known at compile time) would >> definitely be worth not having that array in heap memory. > > You only need pessimistic copies when that copy escapes, and since it > escapes, it needs to live on the heap by definition. Right now an array of > size 1 passed to 4 objects on the heap has one single backing representation. > With pessimistic copies, you'd get 4 times that buffer of size 1, which is > definitely not an improvement. > >> Going back to the literal notion of FSAs — fixed size arrays not necessarily >> on the stack — I think that simply copying Array’s implementation sans >> RangeReplaceableCollection conformance is not a bad way to go. Any >> optimizations used for `let` Arrays could probably be applied to this type >> of FSA. > > We're actually splitting this in multiple directions. John talks of > variable-sized arrays necessarily on the stack. :) > > I see two useful characteristics to fixed-size arrays, which, > uncoincidentally, are what it takes to use them for C interop: > > Their storage is inlined into their container (whether it be the stack or an > object) > Their length is part of their type (and not directly included with the data > itself) > > This is also enough to implement fixed-size arrays not necessarily on the > stack, mind you. > > Félix
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution