1

Suppose there are two arrays, one with n number of Class elements and one with n number of Struct elements. Which will consume more memory? Also what happens when we start manipulating the arrays. Below is what I tried.

class C {
    var a = ""
}

struct S {
    var a = ""
}


func sizeOf<T>(_ value: T) {
    print(MemoryLayout.size(ofValue: value))
}

let classVar = C()
let structVar = S()

let arrayClass = [classVar, classVar, classVar]
var arrayStruct = [structVar, structVar, structVar]

sizeOf(classVar)
sizeOf(structVar)
sizeOf(arrayClass)
sizeOf(arrayStruct)

var newStruct = structVar
newStruct.a = "Value changed"

sizeOf(structVar)
arrayStruct.append(newStruct)
sizeOf(arrayStruct)

Output

8
16
8
8
16
8

Why is struct size greater than class and also why are both the array of the same size? Is it because array itself is a struct? Can someone provide with detailed explanation?

user832
  • 796
  • 5
  • 18
  • Why not allocate a million of each and find out? – tadman Jun 11 '20 at 22:28
  • @tadman I tried appending `10000` elements and the result was same. But it takes a lot of time in the playground to calculate that, allocating a million of each will take even longer. – user832 Jun 11 '20 at 22:36
  • That's at least one data point. It shouldn't take too long to allocate if compiled, mind you, so if that's an option try that. Does that list the total memory footprint of the object? – tadman Jun 11 '20 at 22:42
  • I ran each ```10_000_000``` times and the result was the same – 0-1 Jun 11 '20 at 22:45
  • I ran 10 million iterations with ```enum``` as well with the same result – 0-1 Jun 11 '20 at 22:47
  • Then maybe you have your answer, but it's worth checking the overall process memory footprint to see what differences there are. I'd expect `struct` and `class` to be effectively the same unless you have subclasses involved. – tadman Jun 11 '20 at 22:47
  • @tadman I just tested down 10 subclass layers, all with the same result. – 0-1 Jun 11 '20 at 22:53
  • 1
    @Jonathan If you've got data it's worth adding as an answer. – tadman Jun 11 '20 at 22:53
  • @tadman I noticed that recursive objects give larger numbers – 0-1 Jun 11 '20 at 23:14
  • 3
    Swift structs are generally dependent on the size of their components, in this case `String` has a size of 16 bytes so that is what you're seeing. Classes are generally pointer-sized as they are a reference to memory allocated somewhere. `Array`s themselves are laid out in such a way that they are fixed size no matter what they contain (I would assume that they are a pointer to some underlying implementation). – saagarjha Jun 11 '20 at 23:34
  • Is it ok to say that both the arrays will have same impact on the memory as arrays are structs and elements will be stored in their own memory space and array element will be a pointer to that particular memory? – user832 Jun 12 '20 at 20:13

1 Answers1

1

I think this is related too: Struct Memory Size vs. Class Memory Size

I ran the struct 10,000,000 times
I ran the class 10,000,000 times
I ran suclasses down to 10 layers 10,000,000 times each
I ran enum cases, and initialized enums 10,000,000 times
They all printed 8 (I will provide images)


I did find that doing this prints 16

struct S { struct SS { var a = "" } }
SS() // 10,000,000 times

For both the struct and recursive struct, the actual memory size given by XCode was actually larger around 170MB, I just wanted to point that out.

all structs: ~170 MB (even recursive ones)
all classes: ~97 MB (even subsclassed ones)
all enums: ~20 MB


Massive Subclasses Basic Struct Enum Case Initialized Enum Recursive Struct

0-1
  • 702
  • 1
  • 10
  • 30