Going through the basics of Swift, I noticed that there are two ways of adding items to an array.
One way is using the .append
method, another is using the +=
operator (which allows for the adding of > 2 item arrays).
Is there any difference between using +=
and .append
when you only want to add a single item to the array?
fooArray.append("Bar")
versus
fooArray += ["Bar"]
Both options do the exact same thing - add a value to an array, yet +=
will allow for adding more than one value while .append()
will only allow adding one value
Here's some code that tests which one is faster for adding a single value
var array: [String] = []
var array2: [String] = []
let time1 = NSDate().timeIntervalSince1970
for i in 0...1000000{
array += ["foobar"]
}
let time2 = NSDate().timeIntervalSince1970
let dif1 = time2 - time1
let time3 = NSDate().timeIntervalSince1970
for i in 0...1000000{
array2.append("foobar")
}
let time4 = NSDate().timeIntervalSince1970
let dif2 = time4 - time3
Testing this on an iPhone 6s, dif1
was 1.47393365859985, and dif2
was 0.385605080127716 which is a difference of 1.0883285785 seconds for one million repetitions. (the average time for 100 runs)
This means that for only one repetition, the difference between the two is that .append
will be about 0.000001088 seconds, or 1.088 microseconds faster than using +=
.
In the end, it really doesn't matter which you're using to append one value - it's just personal preference (obviously, if you need to add a million values to an array, you should use .append()
as it will be noticeably faster)
Vikingosegundo has been very helpful in writing this answer, and as per what he said, you could use
func +=<T>(inout left:[T], right: T) -> [T]{
left.append(right)
return left
}
to get the best of both worlds - this will effectively turn array += value
into array.append(value)
(I believe this used to be a feature in older Swift versions, but was later removed)
+=
work?Array
conforms to CollectionType so when you invoke += the following happens:
/// Extend `lhs` with the elements of `rhs`.
public func += <Element, C : CollectionType where C.Generator.Element == Element>
(inout lhs: ${Self}<Element>, rhs: C) {
let rhsCount = numericCast(rhs.count) as Int
let oldCount = lhs.count
let capacity = lhs.capacity
let newCount = oldCount + rhsCount
// Ensure uniqueness, mutability, and sufficient storage. Note that
// for consistency, we need unique lhs even if rhs is empty.
lhs.reserveCapacity(
newCount > capacity ?
max(newCount, _growArrayCapacity(capacity))
: newCount)
(lhs._buffer.firstElementAddress + oldCount).initializeFrom(rhs)
lhs._buffer.count = newCount
}
append
work?/// Append `newElement` to the ${Self}.
///
/// - Complexity: Amortized ${O1}.
public mutating func append(newElement: Element) {
_makeUniqueAndReserveCapacityIfNotUnique()
let oldCount = _getCount()
_reserveCapacityAssumingUniqueBuffer(oldCount)
_appendElementAssumeUniqueAndCapacity(oldCount, newElement: newElement)
}
The implementation of +=
is a generalized implementation of append
(I will not dig into each call inside append
but feel free to check it), and, for that reason, append
should be a tiny better when dealing with only one element.
So I'd go with whichever one you think will suit your code base better, consistency is key and if the difference between the performance of +=
and append
is causing you problems you're probably doing something really wrong. As a food for thought:
Premature optimization is the root of all evil -- DonaldKnuth
public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C) {
self += newElements
}
Edit: As an addendum I personally like vikingosegundo's proposal and would use it to keep consistency using +=
everywhere.
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