As we all know, types in Swift are divided into value type and reference type. Value type will be cloned when passing over and assign, while reference type will only point to the object. In Swift, struct and enum is value type and class is reference type. One interesting fact is, in Swift all built-in types are value types. Not just the traditional Int or Bool, the list also contains String, Array and Dictionary, which would be considered as reference types in most of other languages.

So, how could we benifit from value types? Compared to traditional reference types, an obvious advantage of the value type is the memory alloc and dealloc on the heap being reduced significantly. In Swift, some value types, especially collection ones such as Array and Dictionary, are designed carefully in memory management. In some other languages, instances of a value type are always copied when passed as a parameter or assigned to another variable. But this is not the case for Swift. Copying of instance for a value type will not happen unless it is truly necessary. We might use different variable names for value types in operations like assignment or argument passing, but these instances are the same ones in memory. Consider this:

var a = [1,2,3]
var b = a
let c = b
test(a)

func test(arr: [Int]) {
    for i in arr {
        print(i)
    }
}

The memory alloc only happens in the first line, in which a is initiated. b and c, and even the arr in test method, will be pointing the very same thing in physical memory as a. And remember a is a value type itself, so all this process is on stack. There is no memory alloc and dealloc on the heap at all, which promises a high performance.

Copying of a value type instance will happen when the value itself changed. For example, when you append an extra element to the array, it will get copied:

var a = [1,2,3]
var b = a
b.append(5)
// Memory address for a and b will be different now.

When a collection instance of value type gets copied, all elements of value type will be copied as well, while for all elements of reference type, just the reference will be stored in new collection. This is reasonable because we will never want our reference type refers to another object we never set before:

class MyObject {
    var num = 0
}

var myObject = MyObject()
var a = [myObject]
var b = a

b.append(myObject)

myObject.num = 100
print(b[0].num)   //100
print(b[1].num)   //100

// Changes of myObject involved b[0] and b[1] as well.

Although the purpose of designing array and dictionary a value type is for thread safety, it benefits on performance when there is no large set of elements in the collection. In Cocoa framework, immutable collections are dominant. By using a value type instead of reference type, and under the design concept of Swift, memory operation is reduced. However, there is a situation that a collection contains quite a lot of elements, and we need to do adding or removing operation on it. When doing so with Swift value type collection, the entire collection must be copied once the element changes. The performance will be degraded quickly. Fortunately, we can turn back to Foundation in this situation. You can prevent this by using NSMutableArray or NSMutableDictionary instead.

As a conclusion, when using collection type like an array or dictionary, we need to consider which to use depending on the size of the collection. NSMutableArray and NSMutableDictionary would do a good job for large scale of data and/or frequent adding/removing operations, while built-in Array and Dictionary will be better for small and immutable collections.