У меня возникают проблемы с производительностью памяти при выполнении операций со списком областей. У меня есть два объекта, похожих на этот:
final class Contact: Object {
let phones = List<Phone>()
let emails = List<Email>()
}
Теперь я пытаюсь найти возможные сходства между двумя объектами одного типа (например, по крайней мере, одним общим элементом), которые потенциально могут иметь повторяющиеся электронные письма или телефоны. Для этого я использовал Set
операций.
func possibleDuplicateOf(contact: Contact) {
return !Set(emails).isDisjoint(with: Set(contact.emails)) || !Set(phones).isDisjoint(with: Set(contact.phones))
}
Это функция внутри объекта Contact
. Я знаю, что при преобразовании Realm List в Set или Array производительность падает, и я сильно это чувствую, когда у меня большое количество контактов (10k или больше), потребление памяти возрастает до более чем 1GB.
Поэтому я попытался заменить указанную выше функцию на эту:
func possibleDuplicateOf(contact: Contact) {
let emailsInCommon = emails.contains(where: contact.emails.contains)
let phonesInCommon = phones.contains(where: contact.phones.contains)
return emailsInCommon || phonesInCommon
}
Это имеет ту же производительность, что и при использовании наборов.
Метод isEqual в электронных письмах и телефонах - это простое сравнение строк:
extension Email {
static func ==(lhs: Email, rhs: Email) -> Bool {
return (lhs.email == rhs.email)
}
override func isEqual(_ object: Any?) -> Bool {
guard let object = object as? Email else { return false }
return object == self
}
override var hash: Int {
return email.hashValue
}
}
Email.swift
final class Email: Object {
enum Attribute: String { case primary, secondary }
@objc dynamic var email: String = ""
@objc dynamic var label: String = ""
/* Cloud Properties */
@objc dynamic var attribute_raw: String = ""
var attribute: Attribute {
get {
guard let attributeEnum = Attribute(rawValue: attribute_raw) else { return .primary }
return attributeEnum
}
set { attribute_raw = newValue.rawValue }
}
override static func ignoredProperties() -> [String] {
return ["attribute"]
}
convenience init(email: String, label: String = "email", attribute: Attribute) {
self.init()
self.email = email
self.label = label
self.attribute = attribute
}
}
У меня здесь немного вариантов, я потратил весь день, пытаясь придумать другой подход к этой проблеме, но безуспешно. Если у кого-то есть идея получше, я хотел бы ее услышать :)
Спасибо
Contact
у вас есть списокPhones
иEmails
. Они тоже сущности царства? Если они являются объектами, они могут иметь обратное отношение к объекту Contact. Имея это отношение, вы можете запрашивать необходимую информацию из области, не обрабатывая ее в памяти. - person ilya   schedule 04.12.2018Phone
иEmail
. - person ilya   schedule 04.12.2018Set
операции, он будет работать очень быстро и почти не тратит дополнительную память. - person Diogo Antunes   schedule 10.12.2018