Hi Peter, thanks for taking a look. I would expect the compiler should generate a read only static string with the name of the function whenever the #function directive is used. I would expect that should not cause a leak.
If I modify the onSet function to replace a static string as the default value instead of using #function, there is no leak, so this seems like a bug to me. Anyone have other ideas or opinions on this? Thanks, Ed -------------------------------------------------------- import Foundation class A { var counter = 0 { // didSet { onSet("counter") } // no leak didSet { onSet() } // huge leak } var properties = ["counter" : 0] // func onSet(_ name: String = #function) { // leaks // properties[name]! += 1 // } func onSet(_ name: String = "counter") { // no leak properties[name]! += 1 } } var myclass = A() for i in 0..<10000000 { myclass.counter = i } print(myclass.properties["counter"]!) On Sun, Aug 27, 2017 at 6:59 PM, Peter Nicholls < swiftu...@peternicholls.co.uk> wrote: > I looked in to the memory alloc and every time the “leak” iterates it’s > creating an string item on the auto release stack with “counter” - a few > million of them, compared to just 1 string on the non- leak. It is also > quite a lot slower than the non leak version. > > I looked at the compiled assembly intermediate and at allocation the only > difference is that the non-leak allocates via a register and is just a > byte, but the leak uses a memory pointer is a word and is _unnammed_. > > My thought is that this isn’t a bug at all, it’s how the compiler deals > with an unnamed #function and thus infers _name. > > As i trawled through the assembly seemed to me the non leak is making > efficient use of the registers, through the named #function / _name, where > as the leak version is using actual memory (hence why it is so much slower) > with a view to destroying the autocomplete stack (of 9million odd auto > release objects at 8bytes at a time) when completed. You can see how the > memory stacks! > > Now. As to why and IF Swift is INTENDED to do this, or if indeed you’re > doing something unintended too.... I cannot say. > > If any of the above is incorrect, please chime in. > > Peter Nicholls > First time post. > > > On 27 Aug 2017, at 18:56, Edward Connell via swift-users < > swift-users@swift.org> wrote: > > > > I reported this about a year ago, but it has never been fixed and it > seems like it should be fixed for the Swift 4.0 release. > > > > Here is a simple repro case. If you watch the memory monitor as it runs, > you see memory consumption climb to 2.7GB when using #function, and no > memory increase when using a static string. > > > > import Foundation > > > > class A { > > var counter = 0 { > > // didSet { onSet("counter") } // no leak > > didSet { onSet() } // huge leak > > } > > > > var properties = ["counter" : 0] > > func onSet(_ name: String = #function) { > > properties[name]! += 1 > > } > > } > > > > var myclass = A() > > > > for i in 0..<10000000 { > > myclass.counter = i > > } > > > > print(myclass.properties["counter"]!) > > > > _______________________________________________ > > swift-users mailing list > > swift-users@swift.org > > https://lists.swift.org/mailman/listinfo/swift-users > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users