7

I have been using some functional program to avoid mutating a struct and there are no clear explanation which approach is best in terms of performance.

Can anyone help out and suggest what is the best solution for in terms of performance and memory management in this case?

For example:

Mutating Option

struct User {

    var name:String

    init(name:String) {
         self.name = name
    }

    mutating func change(name:String){
        self.name = name
    }
 }

Non Mutating Option

 struct User {

    var name:String

    init(name:String) {
         self.name = name
    }

    func change(name:String) -> User {
        return User(name: name)
    }
 }
Z.Lin
  • 28,055
  • 6
  • 54
  • 94
Tal Zion
  • 6,308
  • 3
  • 50
  • 73
  • not sure what you mean. Are you talking about let and var? what is your scenario – zombie Apr 03 '17 at 09:43
  • 1
    @zombie When changing a struct, you need to mutate a function. What are the pros and cons – Tal Zion Apr 03 '17 at 21:03
  • 1
    This is still opinion based and should stay closed until edited. 'Best practice'? How is that not opinion based? In your little begging header you mention performance? Since when is performance synonymous with best practice? As for performance, mutation will nearly always win. There you go. – Jared Smith Apr 04 '17 at 12:23
  • Here you go @JaredSmith , I have updated my question to the best interest of the community, as I find a lot are looking for this answer. If you can be kind enough to vote up to reopen my question.. Thanks you! Oh, and regarding performance, I heard conflicting answers than what you have suggested, but would appreciate if you can chip in and answer with detailed explanation so everyone understand what you mean by "mutation will nearly always win". – Tal Zion Apr 04 '17 at 12:30
  • 1
    @TalZion reopened. As for what I meant, when you return a new user instead of mutating an existing one you could possibly have a memory leak if there's a reference to the old one that doesn't get cleaned up, and if you're making a lot of short-lived objects you will likely get longer gc pauses. Whether or not that's the main consideration ('best practice') and that's worth giving up the improvements in reliability, testability, reason-ability, etc. from avoiding side-effects is another matter (and an opinion-based one). – Jared Smith Apr 04 '17 at 12:35
  • 1
    Thank you @JaredSmith , although I'de have to disagree here regarding the reference count, as structs in Swift by definition are value types, not reference types. Classes in Swift do not mutate. Very interesting point regarding longer gc pause. – Tal Zion Apr 04 '17 at 12:43
  • Didn't know that about Swift structs. Generally speaking in a garbage-collected language, making extra allocations puts extra pressure on the gc. – Jared Smith Apr 04 '17 at 12:55
  • Yes, I agree @JaredSmith . Fortunately, Swift behaviors differently, hence, why many seek an answer on this topic. – Tal Zion Apr 04 '17 at 16:53
  • There are some options you have not included. For example, `change` could set `self` to the new User. – matt Mar 22 '23 at 15:48
  • This might help: https://stackoverflow.com/questions/42420713/does-a-mutating-struct-function-in-swift-create-a-new-copy-of-self – Babul Prabhakar May 12 '23 at 09:24

0 Answers0