Подтвердить что ты не робот

Что происходит под шаблоном запроса на выбор, что повышает производительность?

Мне было любопытно, было ли увеличение производительности от создания шаблона запроса на выборки по сравнению с программным созданием NSFetchRequest, поэтому я написал несколько тестов для его измерения. Здесь источник на github.

Одинаковый порядок разницы в симуляторе и на iPhone (измерение интервала времени, чтобы сделать кучу выборки):

just creating an NSFetchRequest:          4.399674
creating a Fetch Request Template:        0.501369
NSFetchRequest with field indexed:        0.407068
Fetch Request Template and field indexed: 0.281876

Оказалось, что в создании шаблона запроса на выборки наблюдается увеличение производительности в 7-9 раз. Я подумал, что, возможно, он создает соответствующий индекс под ним, но когда я создал шаблон запроса на выборку, который соответствует индексированному полю, есть еще более благоприятная производительность.

Хорошо, приятно знать, что это так, но мне очень хотелось бы знать, что происходит в рамках шаблона запроса на выборку, который учитывает прирост производительности?

4b9b3361

Ответ 1

Update

После некоторого профилирования с помощью инструментов получается, что [NSPredicate predicateWithFormat:] здесь не преступник!

Фактическая причина разницы в производительности - дескрипторы сортировки.

В тестах без шаблона используется NSFetchedResultsController, для которого требуется дескриптор сортировки, тогда как на основе шаблонов не указывается дескриптор сортировки.

Если вы добавите дескриптор сортировки ко всем тестам, производительность будет уменьшаться (за исключением индексированного случая.)


Исходный (неправильный) ответ

Снижение производительности связано с тем, что ваш "просто создающий тест NSFetchRequest" вызывает [NSPredicate predicateWithFormat:] для каждой итерации цикла - это очень медленно!

Подумайте об этом - [NSPredicate predicateWithFormat:] должен проанализировать строку и в основном скомпилировать ее во внутреннее представление, используемое Core Data.

Обычным решением является только вызов [NSPredicate predicateWithFormat:] один раз, а затем используйте [NSPredicate predicateWithSubstitutionVariables:], чтобы указать значения, которые будут сравниваться с помощью предиката - это описано в Документация по основным данным - Эффективный импорт данных

Чтобы создать предикат из форматированной строки, структура должна проанализировать строку и создать экземпляры предиката и выражения объекты. Если вы используете одну и ту же форму предиката много раз но изменяя значение одного из выражений постоянного значения на каждое использование, более эффективно создавать предикат один раз, а затем использовать (см. "Создание предикатов" ).

Ответ 2

Из documentation:

Сохраненные запросы на выборку могут включать в себя заполнители переменной замены и, следовательно, служат шаблонами для последующего завершения. получать поэтому шаблоны запросов позволяют предварительно определять запросы с помощью переменные, которые заменяются во время выполнения.

Также см. раздел "Запросы сохраненной выборки" Ссылка на класс NSManagedObjectModel.

Похоже, самое большое преимущество может заключаться в том, что запрос не нужно строить во время выполнения - он предварительно построен, а затем переменные подставляются в запрос, когда это необходимо.