ohr ohr - 21 days ago 6
Swift Question

Swift Array contains function makes build times long

I'm not sure if this belongs in Stack Overflow, if it doesn't please let me know.

I have this piece of code that adds contacts to an array, if a contact with that phone/name combination already exists in the array it does not add it again (meaning no duplicates).

It works as intended but it increases build times dramatically and I am looking for a better way to use

contains
or some other approach.

var contacts = [CNContact]()

let name: String = contact.givenName + " " + contact.middleName + " " + contact.familyName

if (name.stringByReplacingOccurrencesOfString(" ", withString: "")).length > 1
{
if contact.phoneNumbers.count > 0
{
// Check if contacts already contains name/phone combination
if let phoneNumber: String = (contact.phoneNumbers[0].value as? CNPhoneNumber)?.stringValue
{
if contacts.contains({$0.phoneNumbers.count > 0 && ($0.phoneNumbers[0].value as? CNPhoneNumber)?.stringValue == phoneNumber}) &&
contacts.contains({($0.givenName + " " + $0.middleName + " " + $0.familyName) == name})
{ /* Contact with same name/phone combination already exists in array */ }
else { contacts.append(contact) }
}
}
}

Answer

Chained + is the most common cause of slow build times in my experience. When people complain about build times, I always ask "you've got chained +, don't you." Have been right about 90%. For example:

let name: String = contact.givenName + " " + contact.middleName + " " + contact.familyName

and also

contacts.contains({($0.givenName + " " + $0.middleName + " " + $0.familyName) == name})

Use interpolation rather than chained +:

"\(contact.givenName) \(contact.middleName) \(contact.familyName)"

Or join an array:

[contact.givenName, contact.middleName, contact.familyName].joined(separator: " ")

In this particular case, I'd almost certainly make a helper though:

extension Contact {
    var fullName: String {
        return "\(contact.givenName) \(contact.middleName) \(contact.familyName)"
    }
}

Then much of the rest of your code would get simpler.

The problem with chained + is that it has many overloads, and so the compiler has to do a combinatorially explosive search of all the different versions of + it might use here.

Comments