У меня проблемы с iOS-приложением на основе CoreData, когда оно пытается создать исходную БД из данных, отправленных с сервера.По сути, сервер отправляет 1 МБ фрагментов объектов (около 3000 на блок), и клиент iOS десериализует их и записывает их на диск.
Я вижу, что все идет хорошосначала 8 блоков (из 44), затем производительность резко падает, и каждый блок начинает занимать все больше и больше времени, как на рисунке ниже.Практически все время расходуется на [NSManagedObjectContext save]
, как вы можете видеть в данных профилирования Instruments, но также кажется, что приложение больше не работает на 100% CPU по какой-то причине, например, оно ожидает дискового ввода-вывода иличто-то.
Несколько важных фактов о том, как я это делаю:
Каждый кусок обрабатывается в своем собственном NSManagedObjectContext
со своим собственным NSAutoreleasePool
, поэтому между обработкой фрагментов не происходит наращивание объекта в незагруженном контексте.
Не задано NSUndoManager
для любого изконтексты.
Не происходит mergeChangesFromContextDidSaveNotification:
(т. е. контексты чанков не переносят свои изменения в «главный» контекст)
Я использую хранилище данных на базе SQLite в iOS 4.3.
Записываемые записи имеют индексы.
вся синхронизация выполняется в одном фоновом потоке GCD (например, dispatch_queue_create()
и dispatch_async()
).
Понятия не имею, почему производительностьвнезапно падает, как это или что можно сделать для решения этой проблемы.Я осмотрелся и прочитал следующее, но ничего еще не выскочило на меня:
Любые идеи или указатели для того, чтобы сделать это приложение масштабируемым до 100 000 записей в базе данных, будут высоко оценены.
Редактировать - дополнительная статистика
Этот график инструментов показывает ту же симуляцию, что и выше (на iPad2), но включает в себя статистику активности диска, и вы можете довольно ясно увидеть, что все "не работает на 100"Время% CPU ", по-видимому, занято при записи на диск.
Я также выполнил ту же попытку синхронизации, запущенную на симуляторе iOS.Общее использование памяти является более или менее постоянным для каждого чанка, за исключением словаря, который содержит идентификаторы объектов, которые со временем немного растут (но это не объекты CoreData или что-либо, что может повлиять на сохранение, это просто номера NSN).Это диктует небольшой объем памяти по сравнению с общей кучей, поэтому проблема не исчерпывается памятью.
Что интересно в этом тесте, так это то, что инструмент CoreData Save сообщает, что последующие сохранения занимают примерното же время, которое явно конфликтует с информацией о профилировании процессора из первого набора результатов.Похоже, что CoreData считает, что на внесение изменений в БД уходит столько же времени, но сама БД (т. Е. SQLite) внезапно занимает намного больше времени, чтобы фактически передать эти изменения на диск.