swift – 领域列表中的性能问题
发布时间:2020-12-14 04:55:11 所属栏目:百科 来源:网络整理
导读:在Realm List上进行操作时,我遇到了一些内存性能问题.我有两个类似于这个的对象: final class Contact: Object { let phones = ListPhone() let emails = ListEmail()} 现在我试图找到可能有重复电子邮件或电话的两个相同类型的对象(例如,至少一个共同的元
在Realm List上进行操作时,我遇到了一些内存性能问题.我有两个类似于这个的对象:
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时会有性能损失,当我有大量的Contacts(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 } } 我在这里有点选择,我花了整整一天试图想出一个不同的方法解决这个问题,但没有运气.如果有人有更好的主意,我很想听听:) 谢谢 解决方法
每当这样的事情发生时,一个好的开始是使用
Instruments来找出消耗CPU周期和内存的位置.这是一个很好的教程:
Using Time Profiler in Instruments
您省略了进行实际比较的代码,但我怀疑它可能是嵌套的循环或沿着这些行的东西. Realm不知道你的用例,并没有适当地缓存这样的东西. 使用Instruments,很容易找到瓶颈.在你的情况下,这应该工作: final class Contact: Object { let emails = List<Email>() lazy var emailsForDuplicateCheck:Set<Email> = Set(emails) func possibleDuplicateOf(other: Contact) -> Bool { return !emailsForDuplicateCheck.isDisjoint(with: other.emailsForDuplicateCheck) } override static func ignoredProperties() -> [String] { return ["emailsForDuplicateCheck"] } } 并进行比较: // create an array of the contacts to be compared to cache them let contacts = Array(realm.objects(Contact.self)) for contact in contacts { for other in contacts { if contact.possibleDuplicateOf(other: other) { print("Possible duplicate found!") } } } 此实现确保仅提取一次Contact对象,并且仅为每个联系人创建一组电子邮件. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |