I understand the array.count ( the number of elements in the array ). count is useful to iterate over the array's elements. I sort of get the gist of array.capacity
capacity An integer value that represents how many total elements the array can store without reallocation (read-only).
Experiment
I have been playing with the Playground and noticed an array's capacity is an even number ( incremented by 2 )
var arr = [1, 2, 3 , 4, 5, 6, 7]
arr.removeLast() // capacity stays the same after a removal
println(arr.capacity) // 8
println(arr.count) // 6
var arr = [1, 2, 3 , 4, 5, 6]
arr.removeLast()
println(arr.capacity) // 6
println(arr.count) // 5
The question
What is the use of an array capacity ? Please give a concrete example ?
An array's capacity—in particular, its reserveCapacity
method—lets you preallocate space in the array.
If you're adding elements to an array, and you exceed its capacity, then the array must increase its capacity. Since a Swift array stores its elements contiguously in memory, it must reallocate its internal storage and (usually) copy all of its elements from the old storage to the new storage. (Note that NSArray
isn't documented to store its elements contiguously, but we can deduce that Swift Array probably does based on the existence of the withUnsafeMutableBufferPointer
method.)
If you know in advance how many elements you intend to add to the array, you can use the reserveCapacity
method to preset the array's capacity so that it won't need to perform any reallocations (and associated copying).
The only reasons I can think of to ask an array for its capacity are to learn how the system works, and to debug a performance problem.
Usually you don't need to worry about reserving capacity. A reallocation is rarely a performance problem. Swift uses (I believe) an efficient reallocation schedule so that the number of reallocations is logarithmic in the final count of the array. E.g. if you add a million elements one at a time, Swift should perform no more than 20-30 reallocations.
But if you know your array will be very large (like, gigabytes on a Mac or tens of megabytes on an iOS device), or if you are filling the array in a performance-sensitive code path (e.g. filling an audio buffer that will start playing within microseconds), you may want to reserve capacity and avoid reallocations.
You should probably not worry about reserving capacity unless you know reallocations are a problem, either because the profiler shows that they're a bottleneck or because you have other evidence (like audio glitches in the audio buffer example).
What is the use of an array capacity
Basically, the array capacity has no external use. It is there for Swift's internal use. If you know that you will be allocating 100 objects to this array, you could set the capacity in advance as you create the array, and I have seen some people do that in their code; but there is no particular need to do so and no particular gain in doing so. You've looked under the hood and seen something you didn't really need to see. Now that you've seen, you can forget about it.
The total number of elements that the array can contain without
allocating new storage.
Every array reserves a specific amount of memory to hold its contents. When you add elements to an array and that array begins to exceed its reserved capacity, the array allocates a larger region of memory and copies its elements into the new storage. The new storage is a multiple of the old storage's size. This exponential growth strategy means that appending an element happens in constant time, averaging the performance of many append operations. Append operations that trigger reallocation have a performance cost, but they occur less and less often as the array grows larger.
The following example creates an array of integers from an array literal, then appends the elements of another collection. Before appending, the array allocates new storage that is large enough store the resulting elements.
var numbers = [10, 20, 30, 40, 50]
numbers.count == 5
numbers.capacity == 5
numbers.append(contentsOf: stride(from: 60, through: 100, by: 10))
numbers.count == 10
numbers.capacity == 12
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With