使用日期字符串 Swift 解析大型 json 数据时的高 CPU 使用率
High CPU Usage when parsing large json data with Date Strings Swift
我正在开发一个聊天应用程序。我得到包含与对话相关的数据的对话列表。 Json 响应如下所示
[
{
"id": "1021",
"title": "Test Group",
"memberCount": 250,
"isGroup": true,
"ownerId": "18646",
"createdAt": "2017-08-24T12:05:06.000Z",
"type": "private",
"lastReadAt": {
"18646": "2020-01-29T06:48:53.700Z",
"18664": "2020-01-29T07:12:41.613Z",
"18714": "2020-01-29T07:12:41.613Z",
// 247 More Records
},
"unreadMessageCount": 0,
"mute": false,
"isActive": true,
"isAdmin": true,
"isDeleted": false,
"updatedAt": "2020-01-29T07:12:41.124Z",
"lastMessage": {
"id": "18a16164-657c-420a-887d-5408f1479619",
"conversationId": "1021",
"type": "normal",
"createdAt": "2020-01-29T07:12:41.124Z",
"updatedAt": "2020-01-29T07:12:41.124Z",
"body": "hi",
"ownerId": "18646",
"attachments": [],
"owner": {
"id": "18646",
"displayName": "sydney millers",
"profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
},
"mentionedUsers": []
}
},
{
"id": "1021",
"title": "Test Group 2",
"memberCount": 250,
"isGroup": true,
"ownerId": "18646",
"createdAt": "2017-08-24T12:05:06.000Z",
"type": "private",
"lastReadAt": {
"18646": "2020-01-29T06:48:53.700Z",
"18664": "2020-01-29T07:12:41.613Z",
"18714": "2020-01-29T07:12:41.613Z",
// 247 More Records
},
"unreadMessageCount": 0,
"mute": false,
"isActive": true,
"isAdmin": true,
"isDeleted": false,
"updatedAt": "2020-01-29T07:12:41.124Z",
"lastMessage": {
"id": "18a16164-657c-420a-887d-5408f1479619",
"conversationId": "1021",
"type": "normal",
"createdAt": "2020-01-29T07:12:41.124Z",
"updatedAt": "2020-01-29T07:12:41.124Z",
"body": "hi",
"ownerId": "18646",
"attachments": [],
"owner": {
"id": "18646",
"displayName": "sydney millers",
"profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
},
"mentionedUsers": []
}
}
]
lastReadAt
基本上包含群组成员最后一次阅读对话时的信息。现在要获取最后一条消息的状态,无论它是否被所有人阅读并将其放入 table 单元格中,我必须找到最旧的日期并将其与消息日期进行比较。但是要比较日期,我必须将它们从字符串转换为日期。现在假设有 10 个对话,每个对话包含 250 个成员。所以有很多任务,所以我的 cpu 使用率达到 100%。任何更好的解决方案。对于 swift 我使用下面的函数
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform() // Custom Date Transformer Same as of ios default but with a fixed date format.
if let lastReadInfoDic = self.conversation?.lastReadDictionary {
var lastReadData = [String:Date]()
lastReadInfoDic.forEach({(id,date) in
if let memberReadDate = dateTransformer.transformFromJSON(date) {
lastReadData.updateValue(memberReadDate, forKey: id)
}
})
let sortedData = lastReadData.sorted(by: {[=14=].value < .value})
if let oldestReader = sortedData.first {
let oldestReadDate = oldestReader.value
if itemMessageDate <= oldestReadDate {
return .seen
} else {
return .sent
}
}
}
return .sent
}
如果我没看错的话,您需要 self.conversation?.lastReadDictionary
中的最短日期。看起来 lastReadDictionary
是 [String: String]
.
如果是,则使用compactMapValues(_:)
将[String: String]
变成[String: Date]
。接下来,使用 min(_:)
查找最早的日期。
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform()
let oldestReader = conversation?.lastReadDictionary
.compactMapValues { dateTransformer.transformFromJSON([=10=]) }
.min { [=10=].value < .value } // NOTE: Comparing Date objects.
guard let oldestDate = oldestReader?.value else {
return .sent
}
if itemMessageDate <= oldestDate {
return .seen
} else {
return .sent
}
}
是否所有时间字符串都使用 Z
时区?如果是这样,那么您可以使用字符串比较来查找最早的 ISO 时间字符串。获得最早的字符串后,将那个 ISO 时间字符串转换为 Date
.
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform()
let oldestElement = conversation?.lastReadDictionary
.min { [=11=].value < .value } // NOTE: Comparing String objects.
guard let string = oldestElement?.value, let oldestDate = dateTransformer.transformFromJSON(string) else {
return .sent
}
if itemMessageDate <= oldestDate {
return .seen
} else {
return .sent
}
}
我正在开发一个聊天应用程序。我得到包含与对话相关的数据的对话列表。 Json 响应如下所示
[
{
"id": "1021",
"title": "Test Group",
"memberCount": 250,
"isGroup": true,
"ownerId": "18646",
"createdAt": "2017-08-24T12:05:06.000Z",
"type": "private",
"lastReadAt": {
"18646": "2020-01-29T06:48:53.700Z",
"18664": "2020-01-29T07:12:41.613Z",
"18714": "2020-01-29T07:12:41.613Z",
// 247 More Records
},
"unreadMessageCount": 0,
"mute": false,
"isActive": true,
"isAdmin": true,
"isDeleted": false,
"updatedAt": "2020-01-29T07:12:41.124Z",
"lastMessage": {
"id": "18a16164-657c-420a-887d-5408f1479619",
"conversationId": "1021",
"type": "normal",
"createdAt": "2020-01-29T07:12:41.124Z",
"updatedAt": "2020-01-29T07:12:41.124Z",
"body": "hi",
"ownerId": "18646",
"attachments": [],
"owner": {
"id": "18646",
"displayName": "sydney millers",
"profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
},
"mentionedUsers": []
}
},
{
"id": "1021",
"title": "Test Group 2",
"memberCount": 250,
"isGroup": true,
"ownerId": "18646",
"createdAt": "2017-08-24T12:05:06.000Z",
"type": "private",
"lastReadAt": {
"18646": "2020-01-29T06:48:53.700Z",
"18664": "2020-01-29T07:12:41.613Z",
"18714": "2020-01-29T07:12:41.613Z",
// 247 More Records
},
"unreadMessageCount": 0,
"mute": false,
"isActive": true,
"isAdmin": true,
"isDeleted": false,
"updatedAt": "2020-01-29T07:12:41.124Z",
"lastMessage": {
"id": "18a16164-657c-420a-887d-5408f1479619",
"conversationId": "1021",
"type": "normal",
"createdAt": "2020-01-29T07:12:41.124Z",
"updatedAt": "2020-01-29T07:12:41.124Z",
"body": "hi",
"ownerId": "18646",
"attachments": [],
"owner": {
"id": "18646",
"displayName": "sydney millers",
"profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
},
"mentionedUsers": []
}
}
]
lastReadAt
基本上包含群组成员最后一次阅读对话时的信息。现在要获取最后一条消息的状态,无论它是否被所有人阅读并将其放入 table 单元格中,我必须找到最旧的日期并将其与消息日期进行比较。但是要比较日期,我必须将它们从字符串转换为日期。现在假设有 10 个对话,每个对话包含 250 个成员。所以有很多任务,所以我的 cpu 使用率达到 100%。任何更好的解决方案。对于 swift 我使用下面的函数
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform() // Custom Date Transformer Same as of ios default but with a fixed date format.
if let lastReadInfoDic = self.conversation?.lastReadDictionary {
var lastReadData = [String:Date]()
lastReadInfoDic.forEach({(id,date) in
if let memberReadDate = dateTransformer.transformFromJSON(date) {
lastReadData.updateValue(memberReadDate, forKey: id)
}
})
let sortedData = lastReadData.sorted(by: {[=14=].value < .value})
if let oldestReader = sortedData.first {
let oldestReadDate = oldestReader.value
if itemMessageDate <= oldestReadDate {
return .seen
} else {
return .sent
}
}
}
return .sent
}
如果我没看错的话,您需要 self.conversation?.lastReadDictionary
中的最短日期。看起来 lastReadDictionary
是 [String: String]
.
如果是,则使用compactMapValues(_:)
将[String: String]
变成[String: Date]
。接下来,使用 min(_:)
查找最早的日期。
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform()
let oldestReader = conversation?.lastReadDictionary
.compactMapValues { dateTransformer.transformFromJSON([=10=]) }
.min { [=10=].value < .value } // NOTE: Comparing Date objects.
guard let oldestDate = oldestReader?.value else {
return .sent
}
if itemMessageDate <= oldestDate {
return .seen
} else {
return .sent
}
}
是否所有时间字符串都使用 Z
时区?如果是这样,那么您可以使用字符串比较来查找最早的 ISO 时间字符串。获得最早的字符串后,将那个 ISO 时间字符串转换为 Date
.
func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
let dateTransformer = ISODateTransform()
let oldestElement = conversation?.lastReadDictionary
.min { [=11=].value < .value } // NOTE: Comparing String objects.
guard let string = oldestElement?.value, let oldestDate = dateTransformer.transformFromJSON(string) else {
return .sent
}
if itemMessageDate <= oldestDate {
return .seen
} else {
return .sent
}
}