gpt4 book ai didi

ios - 核心数据——高效地查找或创建

转载 作者:可可西里 更新时间:2023-11-01 05:44:51 24 4
gpt4 key购买 nike

根据 Apple 的文档( link )—

There are many situations where you may need to find existing objects (objects already saved in a store) for a set of discrete input values. A simple solution is to create a loop, then for each value in turn execute a fetch to determine whether there is a matching persisted object and so on. This pattern does not scale well. If you profile your application with this pattern, you typically find the fetch to be one of the more expensive operations in the loop (compared to just iterating over a collection of items). Even worse, this pattern turns an O(n) problem into an O(n^2) problem.

It is much more efficient—when possible—to create all the managed objects in a single pass, and then fix up any relationships in a second pass. For example, if you import data that you know does not contain any duplicates (say because your initial data set is empty), you can just create managed objects to represent your data and not do any searches at all. Or if you import "flat" data with no relationships, you can create managed objects for the entire set and weed out (delete) any duplicates before save using a single large IN predicate.

问题 1:考虑到我正在导入的数据没有任何关系,我该如何实现最后一行中描述的内容。

If you do need to follow a find-or-create pattern—say because you're importing heterogeneous data where relationship information is mixed in with attribute information—you can optimize how you find existing objects by reducing to a minimum the number of fetches you execute. How to accomplish this depends on the amount of reference data you have to work with. If you are importing 100 potential new objects, and only have 2000 in your database, fetching all of the existing and caching them may not represent a significant penalty (especially if you have to perform the operation more than once). However, if you have 100,000 items in your database, the memory pressure of keeping those cached may be prohibitive.

You can use a combination of an IN predicate and sorting to reduce your use of Core Data to a single fetch request.

示例代码:

// Get the names to parse in sorted order.
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"]
sortedArrayUsingSelector: @selector(compare:)];

// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:
[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]];

// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
@[ [[NSSortDescriptor alloc] initWithKey: @"employeeID" ascending:YES] ]];
// Execute the fetch.
NSError *error;
NSArray *employeesMatchingNames = [aMOC executeFetchRequest:fetchRequest error:&error];

You end up with two sorted arrays—one with the employee IDs passed into the fetch request, and one with the managed objects that matched them. To process them, you walk the sorted lists following these steps:

Get the next ID and Employee. If the ID doesn't match the Employee ID, create a new Employee for that ID. Get the next Employee: if the IDs match, move to the next ID and Employee.

问题 2:在上面的示例中,我得到了两个如上所述的排序数组。考虑到要插入的所有对象都存在于存储中的最坏情况,无论如何我看不出我可以在 O(n) 时间内解决问题。 Apple 描述了上面的两个步骤,但这是一个 O(n^2) 的工作。对于输入数组中的任何 kth 元素,在输出数组的前 k 元素中可能存在也可能不存在与其匹配的元素。所以在最坏的情况下,复杂度将为 O(nC2) = O(n^2)

因此,我认为 Apple 正在做的是确保 fetch 只处理一次,即使需要 O(n^2) 检查也是如此。如果是这样,那么我会接受这个;但是有没有其他方法可以有效地做到这一点。

请理解,我不想一次又一次地获取 - 为大小为 100 个标识符的输入数组获取一次。

最佳答案

广告。 1 关系的事实在这里并不重要。这个解释只是说如果你从例如下载你的数据一个远程服务器和您的项目有一些 ID,然后您可以在一个请求中从持久存储中获取它们,而不是在单独的请求中获取每个对象。

广告。 2

Apple describes the two steps as above but that is an O(n^2) job.

不是。请仔细阅读这些行:

To process them, you walk the sorted lists following these steps:

Get the next ID and Employee. If the ID doesn't match the Employee ID, create a new Employee for that ID. Get the next Employee: if the IDs match, move to the next ID and Employee.

您同时遍历数组/列表,因此您永远不必进行此检查:“输出数组中的前 k 个元素 中可能存在也可能不存在与其匹配的元素。”您无需检查之前的元素,因为它们已排序,它们肯定不会包含您感兴趣的对象。

关于ios - 核心数据——高效地查找或创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19392571/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com