Search code examples
swiftclassmemorystructprimitive

Swift iOS -Does A Class Object Type Consume More Memory Then A "Primitive" Type?


I know in Swift primitives don't exist but it was the best name I could think of.

I went to a Meetup a couple of weeks ago and the speaker said that a Switch statement consumes slightly more memory then an If-Else statement. I had no idea there was a difference in memory consumption between the 2 and if I had thought about it I would've thought the opposite. Anyway it got me to thinking about my code.

I'm sending data from one vc to another and I can do it 2 different ways.

  1. I can send 2 variables with a value from ClassA to ClassB

  2. I can create a class or struct model that has the same 2 variables as properties and then pass the model from ClassA to ClassB

1st example:

ClassA:UIViewController{

var firstName: String?
var lastName: String?

viewDidLoad...{

    self.firstName = "Veggie"
    self.lastName = "Burger"
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "..."{

              let classB = segue.destination...
              classB.firstName = self.firstName
              classB.lastName = self.lastName
        }
}

ClassB:UIViewController{

var firstName: String?
var lastName: String?

viewDidLoad...{

     self.firstName! ... //do something with it
     self.lastName! ... //do something with it
}
}

2nd Example:

class: Person{
     firstName: String?
     lastName: String?
}


ClassA:UIViewController{

var person: Person?

viewDidLoad...{

    self.person = Person()
    self.person.firstName = "Veggie"
    self.person.lastName = "Burger"
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "..."{

              let classB = segue.destination...
              classB.person = self.person
        }
}

ClassB:UIViewController{

var person: Person?

viewDidLoad...{

     self.person.firstName! ... //do something with it
     self.person.lastName! ... //do something with it
}
}

I know in the 1st example I have 2 different values sitting at 2 different memory addresses but in the 2nd example I have 1 value sitting at 1 memory address. I'm unsure if it's properties are also sitting at 2 different memory addresses or sharing the same one.

Would the 1st example or the 2nd example consume more memory?


Solution

  • Objects (instances of classes) have two machine words of overhead. One which points to the meta class object (which contains all the various information about the object's instance variables, properties, methods, etc.), and another word which contains the reference count and other booking keep data for the object.

    The overhead of these two fields isn't usually. Of course, if you're making lots (100,000s) of small objects, the penalty adds up. And if your object only contains one machine word of real data, but has 2 words of overhead, you're only getting 33% utilization from the memory. The bigger issue is that objects are allocated on the heap, which is an expensive process. Further more, creating destroying references to objects requires synchronized modification of the objects reference count.

    Structs store their fields inline, and instances of structs are stored on the stack. They're incredibly efficient and highly optimizable by the compiler. In most cases, with whole module optimization enabled, most structs don't even exist at runtime, as the compiler is able to just work with the data within them directly. They so efficient, in fact, that everything you might think of as a "primitive" (from a language like Java) is actually implemented as a struct (or maybe an enum, which is similar). For example, Int (and (U)Int8/16/32/64), Character, etc. are all structs.

    But importantly, none of this really matters. Until you've identified a performance issue, you're wasting your time by letting irrelevant factors dictate your code, at the expense of other probably more important factors (readability, maintainability, brevity, etc.).

    If you need to repeatedly deal with pairs of first names and last name, by all means, go ahead and make a Person struct that stores first and last names. That's the point of types. To lift you up form the bit and bytes and bring you to a higher, simpler, level of thinking about your code.

    I would highly recommend you check out Do iOS 2016 - Rob Napier, Once more, with types, a great talk by @RobNapier