简体   繁体   English

保存具有很多冗余信息的对象(带有核心数据)

[英]Save objects with many redundant information (with core data)

I am designing an app in Objective-C that uses a core data structure. 我正在Objective-C中设计一个使用核心数据结构的应用程序。

I have the following structure : 我有以下结构:

@interface classA : NSManagedObject
@property(nonatomic, strong) someType1 * property1;
..
@property(nonatomic, strong) someTypeN * propertyN;
@property(nonatomic, strong) NSSet * children;
@end

and

@interface classB : classA
@property (nonatomic, strong) classA * parent;
@end

I have the following features : 我具有以下功能:

1) Each object of classA will have many children in classB. 1)classA的每个对象在classB中将有许多子代。 (Objects in classB don't have children themselves). (classB中的对象本身没有孩子)。

2) Moreover, most objects of classB will share many properties in common with they parent (for instance, you can think that in most cases, only property1 will differ between an object of classB and the same property in its parent in classA, so for x in classB x.property2 = x.parent.property2 and so on). 2)此外,classB的大多数对象将与它们的父对象共享许多相同的属性(例如,您可以认为在大多数情况下,classB的对象与其父类在classA中的相同属性之间只有property1会有所不同,因此对于classB中的x x.property2 = x.parent.property2,依此类推)。

3) I will only query the database through requests on object of type classA. 3)我将仅通过对classA类型的对象的请求来查询数据库。

I am looking for a way to reduce the disk memory usage of my app by storing only the necessary properties of objects of type classB. 我正在寻找一种方法,通过只存储classB类型的对象的必要属性来减少应用程序的磁盘内存使用量。 For instance, I could keep properties of an object of classB set to nil unless it differs from the one of its parent, defining the getter of classB as : 例如,我可以将classB对象的属性设置为nil,除非它不同于其父对象的属性,将classB的getter定义为:

- (sometypeX*) getPropertyX {
    if (propertyX) return propertyX;
    return parent.propertyX;
}

My questions are : 1) Am I really going to gain disk memory by filling my database with nil values instead of actual values 2) Are there drawbacks to such a construction 3) Are there better ways / design patterns to deal with this issue ? 我的问题是:1)我真的要通过用nil值而不是实际值填充数据库来获取磁盘内存吗?2)这样的构造是否有缺点3)是否有更好的方法/设计模式来处理此问题?

Thanks in advance for any help. 在此先感谢您的帮助。

Core Data is highly optimized. 核心数据已高度优化。 It already does what you're trying to implement using faulting . 它已经完成了您尝试使用faulting实现的功能。 From Faulting and Uniquing in the docs: 从文档中的故障和独特性

Because a fault is not realized, a managed object fault consumes less memory, and managed objects related to a fault are not required to be represented in memory at all. 因为未实现故障,所以管理对象故障消耗的内存更少,并且与故障相关的管理对象根本不需要在内存中表示。

To answer your questions… 要回答您的问题...

1) Am I really going to gain memory by filling my database with nil values instead of actual values 1)我真的要通过用nil值而不是实际值填充数据库来获得内存吗

If you gain any memory with this approach, it's probably insignificant. 如果您通过这种方法获得了任何记忆,则可能微不足道。

2) Are there drawbacks to such a construction 2)这种结构是否有缺点

It adds lots of complexity to your code base without much justification. 它没有太多理由就增加了代码库的复杂性。 It makes your code harder to read, understand, and maintain. 它使您的代码难以阅读,理解和维护。

3) Are there better ways / design patterns to deal with this issue 3)是否有更好的方法/设计模式来解决此问题

Just use Core Data in a way that's easy to understand, and let it handle the optimization unless you have a clear, measurable need to optimize further. 只需以易于理解的方式使用Core Data,然后让它处理优化,除非您有明确,可衡量的进一步优化需求。

I have made some testing following the question I had asked. 我根据提出的问题进行了一些测试。

I tested the following setting : I have a classA with 11 NSString properties and children in classB. 我测试了以下设置:我有一个具有11个NSString属性的classA和classB中的子级。 classB is a subclass of classA with the same properties and a parent property. classB是classA的子类,具有相同的属性和父属性。

I created randomly between 100 and 1000 instances of classA, each of which having between 10 and 1000 children in classB. 我随机创建了100至1000个classA实例,每个实例在classB中具有10至1000个孩子。 For the objects of classA, I set each string property to be a random 10 characters string. 对于classA的对象,我将每个字符串属性设置为随机的10个字符的字符串。

I tested two procedures : - either the fields of the children of an objectA is set to nil - or it is set to its parent property. 我测试了两个过程:-将objectA的子项的字段设置为nil-或将其设置为其父属性。

And I monitored the sizes of my database files. 我监视了数据库文件的大小。

Unfortunately I was not able to extract a linear law from the rate of growth of the files (while this works with only one class, I couldn't figure it out with this more complicated parent/children structure). 不幸的是,我无法从文件的增长速度中提取线性定律(虽然这仅适用于一个类,但对于这种更为复杂的父/子结构我无法弄清楚)。 Moreover I couldn't quite understand the repartition of the sizes between the file ending with .sqlite and the one ending with .sqlite-wal. 此外,我不太理解以.sqlite结尾的文件与以.sqlite-wal结尾的文件之间大小的重新分配。

However in all the regimes tested (where the total db size is between 1 Mb and 100 Mb) I found that I gained around a factor of 3 when using the first procedure compared to the second. 但是,在所有测试的方案中(总db大小在1 Mb和100 Mb之间),我发现与第二种方法相比,使用第一种方法时,我获得了大约3倍的收益。

So for this regime of use not setting some properties seem to lead to a negligible gain in db size. 因此,对于这种使用方式,未设置某些属性似乎导致数据库大小的增加可忽略不计。

Please tell me if you want me to elaborate more on this answer. 请告诉我是否要我详细说明这个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM