Что лучше использовать метод "НайтиСтроки()" или обход в цикле с условием?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)
Но возможны нюансы: например, если в выборку попадает большинство строк ТЗ (вы ведь про таблицу значений спрашивали, или нет?), а потом эти строки как-то обрабатываются в цикле, то экономия времени практически сводится к нулю - цикл сразу по исходной ТЗ отработает не хуже.
что более оптимально и лучше использовать?
Вообще, как правило, встроенные функции платформы работают быстрее, чем их эмуляция кодом.
Но возможны нюансы: например, если в выборку попадает большинство строк ТЗ (вы ведь про таблицу значений спрашивали, или нет?), а потом эти строки как-то обрабатываются в цикле, то экономия времени практически сводится к нулю - цикл сразу по исходной ТЗ отработает не хуже.
(4) не только. Даже если не установлены индексы, Сомневаюсь, что НайтиСтроки использует встроенный язык 1С. Скорее всего НайтиСтроки использует встроенный механизм (предположительно) обхода в цикле, который (предположительно) написан на С++.
Ну и разница должна быть заметна на достаточно большом числе итераций.
Ну и разница должна быть заметна на достаточно большом числе итераций.
(5) Был ряд случаев убедиться, что неиндексированные НайтиСтроки сразу выходят в топ затрат замера производительности. Поэтому таки только. Ну, конечно, ничто и никто не мешает поэкспериментировать самостоятельно.
(6) ок. Вот результаты теста для 1 000 000 итераций:
Тест НайтиСтроки
Найдено: 1
Затрачено время: 52 мс
Тест поиск циклом
Найдено: 1
Затрачено время: 15 329 мс
Тест НайтиСтроки
Найдено: 1
Затрачено время: 52 мс
Тест поиск циклом
Найдено: 1
Затрачено время: 15 329 мс
Прикрепленные файлы:
Тест_НайтиСтроки.epf
(13)
Уверены? Нигде про это не читал.
Вот, результаты (так же для 1 млн записей) при нетипизированной колонки:
Тест НайтиСтроки
Найдено: 1
Затрачено время: 53 мс
Когда вы добавляете типизированную в примитивный тип колонку в ТЗ, 1С-ка автоматически индексирует ее.
Уверены? Нигде про это не читал.
Вот, результаты (так же для 1 млн записей) при нетипизированной колонки:
Тест НайтиСтроки
Найдено: 1
Затрачено время: 53 мс
(7) Ну... Достаточно "академический" набор данных - нет ни строк, ни ссылок (или хотя бы УИД). И зачем-то несколько колонок...
Мне кажется, что и получение поля по имени (СтрТЗ["Кол1"] = СтрокаПоиска) дает дополнительные затраты.
В общем, я к тому, что вероятно, НайтиСтроки может быть и быстрее, чем просто перебор. Но реальный выигрыш будет лишь при индексировании.
Мне кажется, что и получение поля по имени (СтрТЗ["Кол1"] = СтрокаПоиска) дает дополнительные затраты.
В общем, я к тому, что вероятно, НайтиСтроки может быть и быстрее, чем просто перебор. Но реальный выигрыш будет лишь при индексировании.
(9) А отладка отключена?
Вообще, скорость внутренней функции в любом случае быстрее. Индекс - это просто отсортированный массив колонок, поэтому необходимо учитывать время, затраченное на производство этого индекса, которое некоторые коллеги почему-то считают пренебрежительно малым, при том быстрая сортировка - это N * log 2 N, а поиск даже по подстроке - это просто N. Да, если нам нужно сто раз найти разное, то индексация себя оправдает на количестве строк от сотни, но если это разовая ситуация, то толку от индексации НОЛЬ без палочки - это в log 2 N раз дольше, чем просто одинарный проход по строкам таблицы внутренней функцией, которая, предположу, используется и при построении индекса, только при построении индекса она вызывается условно в несколько раз чаще (для сотни элементов - уже в 7 раз почти).
Но да, чтобы это понять, нужно дорасти и переболеть.
Вообще, скорость внутренней функции в любом случае быстрее. Индекс - это просто отсортированный массив колонок, поэтому необходимо учитывать время, затраченное на производство этого индекса, которое некоторые коллеги почему-то считают пренебрежительно малым, при том быстрая сортировка - это N * log 2 N, а поиск даже по подстроке - это просто N. Да, если нам нужно сто раз найти разное, то индексация себя оправдает на количестве строк от сотни, но если это разовая ситуация, то толку от индексации НОЛЬ без палочки - это в log 2 N раз дольше, чем просто одинарный проход по строкам таблицы внутренней функцией, которая, предположу, используется и при построении индекса, только при построении индекса она вызывается условно в несколько раз чаще (для сотни элементов - уже в 7 раз почти).
Но да, чтобы это понять, нужно дорасти и переболеть.
(10)
(8) Провел тест с использованием УИД в колонке.
Тест НайтиСтроки
Затрачено время: 75 мс
Немного больше чем при примитивных типах, но не принципиально.
Теперь внимание!
Замер с индексацией колонки.
Тест НайтиСтроки
Затрачено время: 1 мс
Ок. разница в 74 мс. Но самое интересное:
Время индексации: 4 141
Время индексации портит всю картину. Если НайтиСтроки используются очень часто на одной и той же ТЗ, то возможен выиигрыш. Ну, тут не сложно посчитать, когда этот выигрыш будет.
Но для единоразового поиска индексировать таблицу не имеет никакого смысла.
(8) Провел тест с использованием УИД в колонке.
Тест НайтиСтроки
Затрачено время: 75 мс
Немного больше чем при примитивных типах, но не принципиально.
Теперь внимание!
Замер с индексацией колонки.
Тест НайтиСтроки
Затрачено время: 1 мс
Ок. разница в 74 мс. Но самое интересное:
Время индексации: 4 141
Время индексации портит всю картину. Если НайтиСтроки используются очень часто на одной и той же ТЗ, то возможен выиигрыш. Ну, тут не сложно посчитать, когда этот выигрыш будет.
Но для единоразового поиска индексировать таблицу не имеет никакого смысла.
(15)
С запросами, кстати, та же фигня, но мало кто понимает, что индексация временной таблицы - это не бесплатная операция.
Время индексации: 4 141
Ну народ-то думает, что индексы божественно без временных затьрат сами богами 1С рисуются в квантовом мире... С учетом разницы во времени, без индекса в вашей таблице можно искать полсотни раз, после чего индекс начнет выигрывать.
С запросами, кстати, та же фигня, но мало кто понимает, что индексация временной таблицы - это не бесплатная операция.
НайтиСтроки постоянно нужно проверять массив возвращаемого значения. Если Массив.Количество() > 0.
Уже не получится обратиться, если ничего не найдено, например Массив[0] - будет ошибка.
Уже не получится обратиться, если ничего не найдено, например Массив[0] - будет ошибка.
(19) я переделал тест на заполнение УИД в колонке рандомными значениями из 1000 разных УИД. Т.е. в 1 млн записей заполнены рандомно из массива содержащих 1000 разных УИД.
Вот код:
Все данные по замерам в 15 использовали этот код.
Вот код:
Функция ПолучитьЗаполненнуюТЗ()
МассивУИД = ПолучитьСписокУИД();
ГСЧ = Новый ГенераторСлучайныхЧисел();
ТЗ = Новый ТаблицаЗначений;
Для К = 1 По 10 Цикл
ТЗ.Колонки.Добавить("Кол"+К);
КонецЦикла;
Для К = 1 По КоличествоИтераций Цикл
СтрТЗ = ТЗ.Добавить();
СтрТЗ["Кол1"] = МассивУИД[ГСЧ.СлучайноеЧисло(0,МассивУИД.ВГраница())];
КонецЦикла;
УИДПоиска = МассивУИД[ГСЧ.СлучайноеЧисло(0,МассивУИД.ВГраница())];
СтрокаУИДПоиска = xmlstring(УИДПоиска);
//ВремяНачалаЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах();
//ТЗ.Индексы.Добавить("Кол1");
//ВремяОкончанияЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах();
//Сообщить("Время индексации ТЗ: "+(ВремяОкончанияЗамера - ВремяНачалаЗамера));
Возврат ТЗ;
КонецФункции
Функция ПолучитьСписокУИД()
МассивУИД = Новый Массив;
Для К = 1 По 1000 Цикл
МассивУИД.Добавить(Новый УникальныйИдентификатор());
КонецЦикла;
Возврат МассивУИД;
КонецФункции ПоказатьВсе данные по замерам в 15 использовали этот код.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот