Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between += and append for adding single item to an Array?

Tags:

arrays

ios

swift

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"]
like image 463
ekeen4 Avatar asked Jan 10 '16 01:01

ekeen4


2 Answers

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)

like image 158
Jojodmo Avatar answered Sep 26 '22 17:09

Jojodmo


How does += 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
}

How does 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

Fun fact

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.

like image 42
fpg1503 Avatar answered Sep 25 '22 17:09

fpg1503