1

I have a Core Data model which has an Entity TrainingDiary which contains Day entities. I have set up a couple of test Training Diaries on with 32 Days in it and the other a full import of a live Training Diary which has 5,103 days in it. Days have relationships to each other for yesterday and tomorrow.

I have a derived property on Day which takes a value from yesterday and value from today to calculate a value on today. This worked but when scrolling through the table of days it was relatively slow. Since after a day has past it would be very rare for this value to change I decided it would be better to store the value and calculate it once.

Thus I have a calculation that can be done on a selected set of days. When a diary is first imported it would be performed on all days but after that it would in the vast majority of cases only be calculated on the most recent Day.

When I check the performance of this on my test data I get the following:

  1. Calculating all 32 days in the 32 day Training diary takes 0.4916 seconds of which 0.4866 seconds is spent setting the values on the Core Data model.
  2. Calculating 32 days in the 5,103 day Training diary takes 47.9568 seconds of which 47.9560 seconds is spent setting the values on the Core Data model.

The Core Data model is not being saved. I had wondered whether there were loads of notifications going on so I removed the observer I had set on NSNotification.Name.NSManagedObjectContextObjectsDidChange and I removed my implementation of keyPathsForValuesAffectingValue(forKey:) implementation but it made no difference.

I can import the whole diary from JSON in far less time - that involves creating all the objects and setting every value.

I am at a loss as to why this is. Does any one have any suggestions on what it could be or on steps to investigate this ?

[I'm using XCode9 and SWIFT4]

Steven Lord
  • 253
  • 4
  • 15
  • Have you used the CoreData SQLDebug build setting to see what is happening at the database level? – pbasdf Nov 15 '17 at 13:25
  • didn't know about that. I will check it out. Thanks – Steven Lord Nov 15 '17 at 16:29
  • Is that the same as selecting CoreData under Profile ? If so I did that and there was absolutely no activity in Core Data - which is as expected as all the days are loaded at startup and I hadn;t done any fetches or saves – Steven Lord Nov 15 '17 at 16:33
  • No - it's a change to the scheme to switch on logging - see [here](https://stackoverflow.com/a/6428693/3985749). Once enabled, you should get a load of console messages detailing the calls being made to SQLite whenever you run the app. – pbasdf Nov 15 '17 at 16:37
  • thanks so much,. Thats a great help – Steven Lord Nov 15 '17 at 16:47
  • There is no SQLDebug output during my calculation. – Steven Lord Nov 15 '17 at 16:58
  • I think it must be something to do with notifications in my GUI - I'm new to all this so may have lost track a little as my app got more complex. Anyway - I created new properties in my Core Data model and set those rather than the old ones. I can now calc and set on all 5,103 days in well under a second. – Steven Lord Nov 16 '17 at 10:01
  • Congratulations. Sorry the SQLDebug proved to be a red herring. – pbasdf Nov 16 '17 at 10:03
  • it may have been a red herring but it's very useful to know. Added to my knowledge. Was rather surprised at just how much was going on behind the scenes. – Steven Lord Nov 16 '17 at 11:28

0 Answers0