NSArchiver 与 NSKeyedArchiver 性能对比

Posted

技术标签:

【中文标题】NSArchiver 与 NSKeyedArchiver 性能对比【英文标题】:NSArchiver vs NSKeyedArchiver performance 【发布时间】:2012-02-07 01:09:06 【问题描述】:

为什么 NSKeyedArchiver 的性能这么差?与使用 NSArchiver 相比,大小翻倍。

我正在使用以下行编码一个 NSMutableArray 对象

BOOL result = [NSArchiver archiveRootObject:self.appDataObject.materias toFile:archivePath];

NSMutableArray 包含具有相应 encodeWithCoder 和 initWithCoder 的自定义对象

-(void)encodeWithCoder:(NSCoder *)aCoder


    [aCoder encodeObject: _fileName];
    [aCoder encodeObject: _categoria];
    [aCoder encodeObject: _materia];
    [aCoder encodeObject: _nombre];

    [aCoder encodeObject: _position];
    [aCoder encodeValueOfObjCType:@encode(BOOL) at:&_favorite];



-(id)initWithCoder:(NSCoder *)aDecoder

    if (self=[super init]) 
        [self setFileName:[aDecoder decodeObject]];
        [self setCategoria:[aDecoder decodeObject]];
        [self setMateria:[aDecoder decodeObject]];
        [self setNombre:[aDecoder decodeObject]];

        [self setPosition:[aDecoder decodeObject]];
        [aDecoder decodeValueOfObjCType:@encode(BOOL) at:&_favorite];
    

    return self;

它工作正常,因为它可以正确保存文件,然后我可以取消归档它。它们大约有 3000 个对象,输出文件约为 900kB

当我将归档行更改为:

BOOL result = [NSKeyedArchiver archiveRootObject:self.appDataObject.materias toFile:archivePath];

一切都很神奇但是文件大小增加了一倍以上,达到 2MB

我为什么要问这个?因为我正在开发一个 ios 应用程序,因此失去了对 NSArchiver 的支持。

【问题讨论】:

【参考方案1】:

至于尺寸减小,我认为这与 NSKeyedArchiver 存储引用而不是实际值有关。

我比较了 NSKeyedArchiver 和 NSArchiver,以及一个基于 cocotron 的名为 NSKeylessArchiver 的新类(由于私有 API 状态,NSArchiver 在 iOS 上可能是禁止使用的)。 NSKeylessArchiver 使用引用来减少具有重复字符串或对象的数据的大小,并且如果您不需要键,则可以更快地解码。

没有子对象和 20000 个整数的简单根对象的性能:

|                 |encoding (min/max/avg secs)|decoding (min/max/avg secs)|
|-----------------|:-------------------------:|:-------------------------:|
|NSKeyedArchiver  |  0.2048/0.2453/0.2165     |  6.8919/6.9238/6.9037|
|NSKeylessArchiver|  0.0407/0.0506/0.0451     |  0.0253/0.0330/0.0287|
|NSArchiver       |  0.0094/0.0114/0.0102     |  0.0019/0.0025/0.0020|

更多详情,请参阅Github repo 和blog post。

【讨论】:

【参考方案2】:

我知道这个线程很旧,但你我想考虑使用 NSPropertyListSerialization...

看看这个线程中提到的性能差异: http://www.cocoabuilder.com/archive/cocoa/2221-nspropertylistserialization-vs-nskeyedarchiver-performance.html

【讨论】:

【参考方案3】:

您获得了向前和向后的兼容性。它是键控,这意味着存档必须存储更多信息才能进行键控查找。请参阅此处的参考:Archives and Serialization

【讨论】:

是的,我了解 NSKeyedArchiver 的优点,但如果我不需要向后兼容怎么办?只需要性能?在这个例子中,我什至没有使用键,对象仍然按顺序保存,使用相同的编码器,我只使用“键控”命令,但仍然保存旧方式。该文件在 Iphone 中加载需要超过 15 秒,这对于用户体验来说是很多的。 您是否考虑过替代存储技术,例如代码数据?您是否需要同时提供所有 3000 个对象,或者您可以分页或分块访问它们? 我选择了 NSArchiver,因为它很简单。 NSPropertyListSerialization 不允许自定义对象。而且我不断地查询超过 3000 个项目,所以它们必须在内存中。不记得为什么我停止使用 Core Data,它通常比 Archiver 更有效吗? 如果您不断地查询 3000 个项目,您应该使用 CoreData 还是在活动内存中保留 3000 个项目以外的其他东西?

以上是关于NSArchiver 与 NSKeyedArchiver 性能对比的主要内容,如果未能解决你的问题,请参考以下文章

归档后比较对象

IOS中的数据存储 简单总结

核心数据关系可以有多个目的地吗?

LDAP 与 MYSQL .. JA-SIG CAS 与 LDAP 与 CAS 与 MySQL

python网络编程基础(线程与进程并行与并发同步与异步)

=与==&与&&| 与 || 的区别