Что лучше использовать метод "НайтиСтроки()" или обход в цикле с условием?

1. I_train 22.07.22 23:18 Сейчас в теме
Добрый день, хотел узнать, может кому то известно, что более оптимально и лучше использовать?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. ishelper 23.07.22 01:06 Сейчас в теме
(1)
что более оптимально и лучше использовать?
Вообще, как правило, встроенные функции платформы работают быстрее, чем их эмуляция кодом.

Но возможны нюансы: например, если в выборку попадает большинство строк ТЗ (вы ведь про таблицу значений спрашивали, или нет?), а потом эти строки как-то обрабатываются в цикле, то экономия времени практически сводится к нулю - цикл сразу по исходной ТЗ отработает не хуже.
3. SlavaKron 23.07.22 06:41 Сейчас в теме
(1) Конечно, метод НайтиСтроки() быстрее, особенно, если установлены индексы. Исключением может быть случай, когда он вызывается на тонком клиенте для ДанныеФормыКоллекция из-за неявного серверного вызова.
dehro; I_train; +2 Ответить
4. ImHunter 315 25.07.22 07:17 Сейчас в теме
(1) (3) Я был бы более категоричен:
Конечно, метод НайтиСтроки() быстрее, особенно только, если установлены индексы.
5. spacecraft 25.07.22 08:24 Сейчас в теме
(4) не только. Даже если не установлены индексы, Сомневаюсь, что НайтиСтроки использует встроенный язык 1С. Скорее всего НайтиСтроки использует встроенный механизм (предположительно) обхода в цикле, который (предположительно) написан на С++.
Ну и разница должна быть заметна на достаточно большом числе итераций.
6. ImHunter 315 25.07.22 08:48 Сейчас в теме
(5) Был ряд случаев убедиться, что неиндексированные НайтиСтроки сразу выходят в топ затрат замера производительности. Поэтому таки только. Ну, конечно, ничто и никто не мешает поэкспериментировать самостоятельно.
7. spacecraft 25.07.22 09:42 Сейчас в теме
(6) ок. Вот результаты теста для 1 000 000 итераций:
Тест НайтиСтроки
Найдено: 1
Затрачено время: 52 мс

Тест поиск циклом
Найдено: 1
Затрачено время: 15 329 мс
Прикрепленные файлы:
Тест_НайтиСтроки.epf
independ; starik-2005; +2 Ответить
13. SlavaKron 26.07.22 09:34 Сейчас в теме
(7) Когда вы добавляете типизированную в примитивный тип колонку в ТЗ, 1С-ка автоматически индексирует ее.
14. spacecraft 26.07.22 09:51 Сейчас в теме
(13)
Когда вы добавляете типизированную в примитивный тип колонку в ТЗ, 1С-ка автоматически индексирует ее.

Уверены? Нигде про это не читал.
Вот, результаты (так же для 1 млн записей) при нетипизированной колонки:

Тест НайтиСтроки
Найдено: 1
Затрачено время: 53 мс
17. SlavaKron 26.07.22 17:53 Сейчас в теме
(14) Уже не уверен. Мои рассуждения были основаны на экспериментах 2-х летней давности в этой статье http://forum.infostart.ru/forum9/topic226825/message2486177/#message2486177
Возможно, то было специфическое поведение конкретной платформы.
8. ImHunter 315 25.07.22 09:59 Сейчас в теме
(7) Ну... Достаточно "академический" набор данных - нет ни строк, ни ссылок (или хотя бы УИД). И зачем-то несколько колонок...
Мне кажется, что и получение поля по имени (СтрТЗ["Кол1"] = СтрокаПоиска) дает дополнительные затраты.

В общем, я к тому, что вероятно, НайтиСтроки может быть и быстрее, чем просто перебор. Но реальный выигрыш будет лишь при индексировании.
9. spacecraft 25.07.22 10:04 Сейчас в теме
(8) а как же "только" ? :)
Просто тупой перебор циклом без кода внутри:

Найдено: 0
Затрачено время: 4 554 мс
Тест поиск циклом
11. starik-2005 3039 25.07.22 10:46 Сейчас в теме
(9) А отладка отключена?

Вообще, скорость внутренней функции в любом случае быстрее. Индекс - это просто отсортированный массив колонок, поэтому необходимо учитывать время, затраченное на производство этого индекса, которое некоторые коллеги почему-то считают пренебрежительно малым, при том быстрая сортировка - это N * log 2 N, а поиск даже по подстроке - это просто N. Да, если нам нужно сто раз найти разное, то индексация себя оправдает на количестве строк от сотни, но если это разовая ситуация, то толку от индексации НОЛЬ без палочки - это в log 2 N раз дольше, чем просто одинарный проход по строкам таблицы внутренней функцией, которая, предположу, используется и при построении индекса, только при построении индекса она вызывается условно в несколько раз чаще (для сотни элементов - уже в 7 раз почти).

Но да, чтобы это понять, нужно дорасти и переболеть.
spacecraft; +1 Ответить
12. spacecraft 25.07.22 10:57 Сейчас в теме
(11)
А отладка отключена?

конечно. с ней замеры на поиск в цикле будут еще больше.
15. spacecraft 26.07.22 11:19 Сейчас в теме
(10)
(8) Провел тест с использованием УИД в колонке.

Тест НайтиСтроки
Затрачено время: 75 мс

Немного больше чем при примитивных типах, но не принципиально.

Теперь внимание!
Замер с индексацией колонки.

Тест НайтиСтроки
Затрачено время: 1 мс

Ок. разница в 74 мс. Но самое интересное:
Время индексации: 4 141

Время индексации портит всю картину. Если НайтиСтроки используются очень часто на одной и той же ТЗ, то возможен выиигрыш. Ну, тут не сложно посчитать, когда этот выигрыш будет.
Но для единоразового поиска индексировать таблицу не имеет никакого смысла.
starik-2005; +1 Ответить
18. starik-2005 3039 26.07.22 20:47 Сейчас в теме
(15)
Время индексации: 4 141
Ну народ-то думает, что индексы божественно без временных затьрат сами богами 1С рисуются в квантовом мире... С учетом разницы во времени, без индекса в вашей таблице можно искать полсотни раз, после чего индекс начнет выигрывать.

С запросами, кстати, та же фигня, но мало кто понимает, что индексация временной таблицы - это не бесплатная операция.
10. ImHunter 315 25.07.22 10:08 Сейчас в теме
(9) Только - это к тому, что мало смысла использовать НайтиСтроки без индекса. Все равно, что ехать только на первой передаче.
16. user686924_shipikVV 26.07.22 12:07 Сейчас в теме
НайтиСтроки постоянно нужно проверять массив возвращаемого значения. Если Массив.Количество() > 0.

Уже не получится обратиться, если ничего не найдено, например Массив[0] - будет ошибка.
19. ImHunter 315 27.07.22 06:36 Сейчас в теме
(15) Так-то с тестовыми данными косячек имеет место. Значения всей колонки (Кол1) уникальны.
20. spacecraft 27.07.22 07:44 Сейчас в теме
(19) я переделал тест на заполнение УИД в колонке рандомными значениями из 1000 разных УИД. Т.е. в 1 млн записей заполнены рандомно из массива содержащих 1000 разных УИД.
Вот код:
Функция ПолучитьЗаполненнуюТЗ()

	МассивУИД = ПолучитьСписокУИД();
	ГСЧ = Новый ГенераторСлучайныхЧисел();

	ТЗ = Новый ТаблицаЗначений;
	Для К = 1 По 10 Цикл
		ТЗ.Колонки.Добавить("Кол"+К);
	КонецЦикла;
	
	Для К = 1 По КоличествоИтераций Цикл
		СтрТЗ = ТЗ.Добавить();
		СтрТЗ["Кол1"] = МассивУИД[ГСЧ.СлучайноеЧисло(0,МассивУИД.ВГраница())];
	КонецЦикла;
	УИДПоиска = МассивУИД[ГСЧ.СлучайноеЧисло(0,МассивУИД.ВГраница())];
	СтрокаУИДПоиска = xmlstring(УИДПоиска);
	//ВремяНачалаЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//ТЗ.Индексы.Добавить("Кол1");
	//ВремяОкончанияЗамера = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Сообщить("Время индексации ТЗ: "+(ВремяОкончанияЗамера - ВремяНачалаЗамера));
	Возврат ТЗ;
КонецФункции

Функция ПолучитьСписокУИД()
	МассивУИД = Новый Массив;
	Для К = 1 По 1000 Цикл
		МассивУИД.Добавить(Новый УникальныйИдентификатор());
	КонецЦикла;
	Возврат МассивУИД;
КонецФункции
Показать


Все данные по замерам в 15 использовали этот код.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот