我应该多久保存一次Core Data?

时间:2022-09-16 11:17:57

I'm working on an application backed by Core Data. Right now, I'm saving the Object Context as and when I add or delete an entity to and from the Context. I'm afraid it will affect the performance, so I was thinking of delaying the save. In fact, I could delay it all the way until the application is gonna terminate. Is it too risky to save the data only when the application is about to close? How often should I call the save on Object Context?

我正在开发一个由Core Data支持的应用程序。现在,当我在Context中添加或删除实体时,我正在保存对象上下文。我担心它会影响性能,所以我想延迟保存。事实上,我可以一直延迟它直到应用程序终止。仅在应用程序即将关闭时保存数据是否风险太大?我应该多久调用一次对象上下文的保存?

I was thinking of having a separate thread handle the save: it will wait on a semaphore. Every time any part of the application calls a helper/util method to save the Core Data, it will decrement the semaphore. When it is down to zero, the "save thread" will do a save once and it increments the semaphore to a, say, 5, and then sleep again.

我想有一个单独的线程处理保存:它将等待信号量。每次应用程序的任何部分调用helper / util方法来保存Core Data时,它都会减少信号量。当它降到零时,“保存线程”将执行一次保存并将信号量递增到a,比如说5,然后再次休眠。

Any good recommendation? Thanks!

有什么好建议吗?谢谢!

3 个解决方案

#1


10  

You should save frequently. The actual performance of the save operation has a lot to do with which persistent store type you're using. Since binary and XML stores are atomic, they need to be completely rewritten to disk on every save. As your object graph grows, this can really slow down your application. The SQLite store, on the other hand, is much easier to write to incrementally. So, while there will be some stuff that gets written above and beyond the objects you're saving, the overhead is much lower than with the atomic store types. Saves affecting only a few objects will always be fast, regardless of overall object graph size.

你应该经常保存。保存操作的实际性能与您正在使用的持久性存储类型有很大关系。由于二进制和XML存储是原子的,因此需要在每次保存时将它们完全重写为磁盘。随着对象图的增长,这可能会使您的应用程序变慢。另一方面,SQLite存储更容易逐步写入。因此,虽然会有一些东西写在你正在保存的对象之上和之外,但开销远远低于原子存储类型。无论整体对象图形大小如何,仅保存仅影响少数对象的保存总是很快。

That said, if you're importing data in a loop, say, I would wait until the end of the complete operation to save rather than saving on each iteration. Your primary goal should be to prevent data loss. (I have found that users don't care for that very much!) Performance should be a close second. You may have to do some work to balance the frequency of saving against performance, but the solution you outline above seems like overkill unless you've identified a specific and significant performance issue.

也就是说,如果你在一个循环中导入数据,比方说,我会等到完成操作结束时保存而不是保存每次迭代。您的主要目标应该是防止数据丢失。 (我发现用户并不关心这一点!)性能应该紧随其后。您可能需要做一些工作来平衡保存与性能的频率,但除非您已经确定了特定且重要的性能问题,否则您在上面概述的解决方案似乎过度。

#2


0  

The best way I think, is to save after every object. If something ever happens such as a sudden crash nothing will be lost.

我认为最好的方法是在每个物体之后保存。如果发生突然崩溃等事情,将不会丢失任何东西。

Some performance enhancements, if you adding a lot of objects is to batch. Add all objects to the context than save. This is good for example if you adding a lot objects in a loop. Your idea is similar, but there could be a long time between saves, in which the program could crash.

如果添加大量对象,一些性能增强是批量处理。将所有对象添加到上下文而不是保存。例如,如果在循环中添加批次对象,这很好。你的想法很相似,但是保存之间可能会有很长时间,程序可能会崩溃。

I don't think adding a single object would be a that much of a performance problem. How big are your objects, do they contain a lot of data?

我不认为添加单个对象会是一个很大的性能问题。你的对象有多大,它们是否包含大量数据?

#3


0  

One issue not mentioned here in other answers is that your solution, which involves using a background thread, should not be operating on a managed object context used in another thread. Generally you make a new MOC for background threads, but that would defeat the purpose of saving if you saved to a different/unmodified background MOC.

其他答案中未提及的一个问题是,您的解决方案(涉及使用后台线程)不应在另一个线程中使用的托管对象上下文上运行。通常,您为后台线程创建一个新的MOC,但如果您保存到不同/未修改的背景MOC,则会失败保存的目的。

So a few answers to your question:

所以你的问题有几个答案:

  1. You would need to call back your original thread to save the MOC
  2. 您需要回调原始线程以保存MOC
  3. As the current accepted answers suggests the whole counter might be overkill for your needs unless a performance issue was measured.
  4. 正如目前接受的答案所示,除非衡量绩效问题,否则整个计数器可能对您的需求而言过度。
  5. If a performance issue WAS measured, you could take a simple throttling technique where you set a limit of, say, 1 save per 10 seconds. Store the Date of the last time you saved. When your save function is called always make sure the current time is > 10 seconds since your last save otherwise, early return.
  6. 如果测量了性能问题,您可以采用简单的限制技术,例如,每10秒设置一次限制。存储上次保存的日期。当你的保存功能被调用时,请确保自上次保存后当前时间> 10秒,否则提前返回。

You really want to be saving immediately as much as possible, so at the very least my recommendation is to throttle rather than arbitrarily set any timer or countdown.

你真的希望尽可能地立即保存,所以至少我的建议是节流而不是任意设置任何计时器或倒计时。

#1


10  

You should save frequently. The actual performance of the save operation has a lot to do with which persistent store type you're using. Since binary and XML stores are atomic, they need to be completely rewritten to disk on every save. As your object graph grows, this can really slow down your application. The SQLite store, on the other hand, is much easier to write to incrementally. So, while there will be some stuff that gets written above and beyond the objects you're saving, the overhead is much lower than with the atomic store types. Saves affecting only a few objects will always be fast, regardless of overall object graph size.

你应该经常保存。保存操作的实际性能与您正在使用的持久性存储类型有很大关系。由于二进制和XML存储是原子的,因此需要在每次保存时将它们完全重写为磁盘。随着对象图的增长,这可能会使您的应用程序变慢。另一方面,SQLite存储更容易逐步写入。因此,虽然会有一些东西写在你正在保存的对象之上和之外,但开销远远低于原子存储类型。无论整体对象图形大小如何,仅保存仅影响少数对象的保存总是很快。

That said, if you're importing data in a loop, say, I would wait until the end of the complete operation to save rather than saving on each iteration. Your primary goal should be to prevent data loss. (I have found that users don't care for that very much!) Performance should be a close second. You may have to do some work to balance the frequency of saving against performance, but the solution you outline above seems like overkill unless you've identified a specific and significant performance issue.

也就是说,如果你在一个循环中导入数据,比方说,我会等到完成操作结束时保存而不是保存每次迭代。您的主要目标应该是防止数据丢失。 (我发现用户并不关心这一点!)性能应该紧随其后。您可能需要做一些工作来平衡保存与性能的频率,但除非您已经确定了特定且重要的性能问题,否则您在上面概述的解决方案似乎过度。

#2


0  

The best way I think, is to save after every object. If something ever happens such as a sudden crash nothing will be lost.

我认为最好的方法是在每个物体之后保存。如果发生突然崩溃等事情,将不会丢失任何东西。

Some performance enhancements, if you adding a lot of objects is to batch. Add all objects to the context than save. This is good for example if you adding a lot objects in a loop. Your idea is similar, but there could be a long time between saves, in which the program could crash.

如果添加大量对象,一些性能增强是批量处理。将所有对象添加到上下文而不是保存。例如,如果在循环中添加批次对象,这很好。你的想法很相似,但是保存之间可能会有很长时间,程序可能会崩溃。

I don't think adding a single object would be a that much of a performance problem. How big are your objects, do they contain a lot of data?

我不认为添加单个对象会是一个很大的性能问题。你的对象有多大,它们是否包含大量数据?

#3


0  

One issue not mentioned here in other answers is that your solution, which involves using a background thread, should not be operating on a managed object context used in another thread. Generally you make a new MOC for background threads, but that would defeat the purpose of saving if you saved to a different/unmodified background MOC.

其他答案中未提及的一个问题是,您的解决方案(涉及使用后台线程)不应在另一个线程中使用的托管对象上下文上运行。通常,您为后台线程创建一个新的MOC,但如果您保存到不同/未修改的背景MOC,则会失败保存的目的。

So a few answers to your question:

所以你的问题有几个答案:

  1. You would need to call back your original thread to save the MOC
  2. 您需要回调原始线程以保存MOC
  3. As the current accepted answers suggests the whole counter might be overkill for your needs unless a performance issue was measured.
  4. 正如目前接受的答案所示,除非衡量绩效问题,否则整个计数器可能对您的需求而言过度。
  5. If a performance issue WAS measured, you could take a simple throttling technique where you set a limit of, say, 1 save per 10 seconds. Store the Date of the last time you saved. When your save function is called always make sure the current time is > 10 seconds since your last save otherwise, early return.
  6. 如果测量了性能问题,您可以采用简单的限制技术,例如,每10秒设置一次限制。存储上次保存的日期。当你的保存功能被调用时,请确保自上次保存后当前时间> 10秒,否则提前返回。

You really want to be saving immediately as much as possible, so at the very least my recommendation is to throttle rather than arbitrarily set any timer or countdown.

你真的希望尽可能地立即保存,所以至少我的建议是节流而不是任意设置任何计时器或倒计时。