on Tue Aug 09 2016, Fritz Anderson <swift-users-AT-swift.org> wrote:
> I’m sending directly to those who took time over my question, because, per > Michael’s request, I have a > minimal case to attach. Phrases in boldface are for skimmability, not > shouting. > > Strip out my use case (I’m encouraged that Dave recapitulated exactly > what I was asking about). My remaining question is: How do you safely > reuse a class reference as the backing store for a struct? Yes, it’s > done all the time, but the trick requirement is that I want to chain > the funcs that do it; chained value returns are immutable; and as far > as I could tell, you can’t get CoW-safe reuse without mutating > self. The result is that you are forced to make expensive copies of > the backing store every time. Joe’s solution looked promising in that > it purported to pass the CoW buffer (if possible) out of the func > after doing all the mutation internally. > > I couldn’t figure out how the answer Joe gave could work: His code > duplicates the struct’s original reference into a copy of the struct, > after which he expects the runtime to report (when possible) that no > such duplicate exists. I asked how this could be, as my attempt to > replicate in a playground showed the reference was never found unique > — which is what I had intuitively expected. Well, a playground is a terrible way to check this, since lifetimes don't necessarily obey the normal rules, but... you're right, it doesn't seem to be workable today. > > > He says this fundamental design pattern in Swift works only if you > change the semantics of the language by turning on the > optimizer. When you count performance characteristics as semantics, yes. > (Sorry to be all Asperger's about it, but nobody corrected me the > first time I put it this way.) Actually I can't even get it to happen with the optimizer on in my tests. > I have many, many questions, I might even hazard objections, but > they’re moot: Optimized or not, that code never reuses the backing > object. > > The attached project was built with Xcode 8.0b5. It uses Joe’s code > (except I still must use isUniquelyReferencedNonObjC(_:)). I run > addInts(x:, y:) and check two ways whether the reference was found > unique. Same result, optimized or not. > > It occurred to me that the globals s_x and s_y might bump the reference > count. I removed them and used this > instead: > > let s_result = addInts(x: S(c: C(value: 99)), y: S(c: C(value: -98))) > > Still no unique references. > > I recognize I am taking up a lot of god time mere days before a major > release, when the likeliest outcome is that I’m a jackass. I don't think so. What's more likely is that we could be optimizing better. > My concern runs deeper than what’s in this message, but I shouldn't > muddy the waters. Those deeper things can go back to the public once > I understand the issue better (or you boot me back). > > --- > > Context (supplementary, no need to spend time) > > If seeing what I’m trying to do helps, I’ve attached my attempt. I’m > sure there are defects in API style, safety, and correctness. I’d have > done more if I hadn’t suspended the project over this issue. Class > FloatBuffer is the backing store; ManagedFloatBuffer is the wrapper > class that does all the operations. None of the operations are > declared mutating. > > Anything that calls (unary|binary)Operator returns a fresh > ManagedFloatBuffer every time; structs and their buffers are created > and initialized every time — intentionally. It seems to work well > under gentle use. > > Callers of mutabilityWrapper preserve the receiver’s backing buffer > whenever possible and mutate it in-place. Those funcs always return > self. These might be a big win; I can’t tell because I’ve never been > able to get unique references. Because there’s an allocation (possibly > initialization) every time, they are no better than the > (unary|binary)Operator funcs. malloc and friends take up a significant > amount of time on the scale of vector math. > > Both flavors can cascade; the only problem is that the “in-place” > methods don’t live up to the name. The question of how to optimize the evaluation of non-mutating expressions using in-place operations is an old one. Once upon a time we were pursuing language features for that purpose (https://github.com/apple/swift/blob/master/docs/proposals/Inplace.rst) but that particular approach is... an ex-approach ;-). -- -Dave _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users