在 iPhone 上保持对象图闪烁的最佳方法
我在 iPhone 平台上有一个 Objective-C 对象图,我希望在关闭应用程序时继续闪烁。该图大约有 100k-200k 个对象,并且包含许多循环(按设计)。我需要能够尽快读/写这个图。
到目前为止,我已经尝试过使用 NSCoder。这不仅会与循环发生冲突,而且还需要很长时间和大量内存来保存该图 - 可能是因为在幕后使用了 XML 文档。我还使用了 SQLite 数据库,但单步执行这么多行也需要大量时间。
我考虑过使用 Core-Data,但担心我会遇到与 SQLite 或 NSCoder 相同的问题,因为我相信 core-data 的后备存储将以相同的方式工作。
那么有没有其他方法可以以轻量级的方式处理这个对象图的持久性——理想情况下我想要像 Java 的序列化这样的东西?我一直在考虑尝试 Tokyo Cabinet 或将一堆 C 结构占用的内存写入磁盘 -但这将需要大量的重写工作。
I have an object graph in Objective-C on the iPhone platform that I wish to persist to flash when closing the app. The graph has about 100k-200k objects and contains many loops (by design). I need to be able to read/write this graph as quickly as possible.
So far I have tried using NSCoder. This not only struggles with the loops but also takes an age and a significant amount of memory to persist the graph - possibly because an XML document is used under the covers. I have also used an SQLite database but stepping through that many rows also takes a significant amount of time.
I have considered using Core-Data but fear I will suffer the same issues as SQLite or NSCoder as I believe the backing stores to core-data will work in the same way.
So is there any other way I can handle the persistence of this object graph in a lightweight way - ideally I'd like something like Java's serialization? I've been thinking of trying Tokyo Cabinet or writing the memory occupied by bunch of C structs out to disk - but that's going to be a lot of rewrite work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议重写为 c 结构。我知道这会很痛苦,但它不仅可以快速写入磁盘,而且性能应该会更好。
在有人感到不安之前,我并不是说人们应该总是使用结构体,但在某些情况下这实际上对性能更好。特别是如果您一次预先分配内存为 20k 个连续块(带有指向块的指针),而不是在重复循环中创建/分配大量小块。
即,如果您的循环不断分配对象,则会减慢速度。如果您预先分配了 1000 个结构体并且只有一个指针数组(或单个指针),那么速度会快很多。
(我曾经遇到过这样的情况,即使是我的桌面 Mac 也太慢,并且没有足够的内存来处理连续创建的数百万个对象)
I would reccomend re-writing as c structs. I know it will be a pain, but not only will it be quick to write to disk but should perform much better.
Before anyone gets upset, I am not saying people should always use structs, but there are some situations where this is actually better for performance. Especially if you pre-allocate your memory in say 20k contiguous blocks at a time (with pointers into the block), rather than creating/allocating lots of little chunks within a repeated loop.
ie if your loop continually allocates objects, that is going to slow it down. If you have preallocated 1000 structs and just have an array of pointers (or a single pointer) then this is a large magnitude faster.
(I have had situations where even my desktop mac was too slow and did not have enough memory to cope with those millions of objects being created in a row)
我强烈建议您再看一下 Core Data,而不是自己动手。 Core Data 是从头开始设计的持久对象图。基于 NSCoder 的存档,就像您所描述的那样,要求您将整个对象图存储在内存中,并且所有写入都是原子的。 Core Data 根据需要将对象移入和移出内存,并且只能将图形中已更改的部分写入磁盘(通过 SQLite)。
如果您阅读了核心数据编程指南或他们的教程指南,您可以看出他们在性能优化上下了很多心思。如果您遵循 Apple 的建议(这似乎违反直觉,例如他们建议在某些时候对数据结构进行非规范化),您可以从数据模型中获得比您预期更高的性能。我见过一些基准测试,其中 Core Data 在您正在查看的大小的数据库中轻松击败手动调整的 SQLite 进行数据访问。
在 iPhone 上,当使用控制获取的批量大小以及 NSFetchedResultsController 中的非常好的帮助器类时,您还具有一些内存优势。
构建图表的原理验证核心数据实现并将其与现有数据存储方法进行比较应该不需要那么长时间。
Rather than rolling your own, I'd highly recommend taking another look at Core Data. Core Data was designed from the ground up for persisting object graphs. An NSCoder-based archive, like the one you describe, requires you to have the entire object graph in memory and all writes are atomic. Core Data brings objects in and out of memory as needed, and can only write the part of your graph that has changed to disk (via SQLite).
If you read the Core Data Programming Guide or their tutorial guide, you can see that they've put a lot of thought into performance optimizations. If you follow Apple's recommendations (which can seem counterintuitive, like their suggestion to denormalize your data structures at some points), you can squeeze a lot more performance out of your data model than you'd expect. I've seen benchmarks where Core Data handily beat hand-tuned SQLite for data access within databases of the size you're looking at.
On the iPhone, you also have some memory advantages when using controlling the batch size of fetches and a very nice helper class in NSFetchedResultsController.
It shouldn't take that long to build up a proof-of-principle Core Data implementation of your graph to compare it to your existing data storage methods.