Swift Arrays & Memory

Here are some thoughts I’d like to share when it comes to Arrays in Swift.
If you’re looking for more information, check out this very good post about memory management in Rust and Swift.

Contiguous Memory

Apple Docs are quite explicit :

For arrays [memory] storage can be a contiguous block of memory or an instance of NSArray.

Arrays are stored in a contiguous block of memory, of course they are.
This is nothing new, but if that’s so, what happens when you append an element to an Array?

Memory Relocation

Relocation occurs when the size of an object exceeds the memory available in its block.
Seems so obvious while reading, isn’t it?
The object is moved to a larger block and the address changes.
This is also possible causes of Memory Leaks, but I leave this story for an other day.
Suppose you are in a very busy and threaded environment… An array changes address… What will happen? Will all the threads be able to access the values properly?

Bad Access and Heap Corruption

Sometimes things might go bad.
You will get a shitty EXC_BAD_ACCESS with little-to-no explanation.
If you’re lucky, you will notice that the address of the incriminated array in the debugger differs from the one that caused the error – of course, it has been moved!
Put together relocation and leaks, and in the worst case you’ll get an Heap Corruption.

How to avoid Array Relocation

My advice is to take this seriously from the start.
Do not fear to write a few more lines of code and reserve capacity for array elements, so they won’t be relocated.
This can be done easily by calling the method reserveCapacity(:_) :

var fruits = ["banana", "strawberry"]
fruit.reserveCapacity(5)
fruit.append("apple")
fruit.append("google") // Not a fruit, but for par condicio
fruit.append("an other banana")

You can also reserve memory you don’t use, which might be an easy option if you don’t know the exact number of elements.

Extension of the day

I love extensions.
If you are particularly lazy – like I am, that’s why a love extension – check this simple extension, that will allow you to init an empty array and reserve capacity in one line.

var fruits = [String](withReservedCapacity: 5)

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

w

Connessione a %s...