Производительность способов обхода таблицы значений по группировке

01.09.25

Разработка - Математика и алгоритмы

Сравнение производительности двух способов обхода таблицы значений по группировке.

Бесплатные

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Узнавайте о новых бесплатных решениях в нашей телеграм-группе Инфостарт БЕСПЛАТНО

Наименование Скачано Бесплатно
Производительность способов обхода таблицы значений по группировке
.epf 6,98Kb
16 Скачать бесплатно

Понадобилось обработать таблицу значений разбитую на группы. В зависимости от наития в разных местах использовал оба способа выборки, но при финальной сборке решил навести порядок и накидал обработку для теста.

Вариант 1. Сортировка таблицы по полю группировки и сравнение поля группировки с флагом при обходе строк.

Таб1 = Таб.Скопировать();
Рез1 = Новый Соответствие();
СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
сГруппировка = "";
Таб1.Сортировать("Группировка");
Для каждого сСтрока Из Таб1 Цикл
	Если сСтрока.Группировка <> сГруппировка Тогда
		сГруппировка = сСтрока.Группировка;
		Рез1.Вставить(сГруппировка, Новый Массив);
	КонецЕсли;
	Рез1[сГруппировка].Добавить(сСтрока.Значение);
КонецЦикла;
ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
Сообщить(СтрШаблон("Обход сортированной таблицы: %1 сек.", ВремяЗамер));
Таб1 = Неопределено;
Рез1 = Неопределено;

Вариант 2:

Выгрузка колонки группировки  в массив. Обход массива с отбор строк методом "НайтиСтроки".

Таб3 = Таб.Скопировать();
Рез3 = Новый Соответствие();
СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
Таб3.Индексы.Добавить("Группировка");
Группировки = Таб3.Скопировать(,"Группировка");
Группировки.Свернуть("Группировка");
Для каждого сСтрока Из Группировки Цикл
	сМассивНайденных = Таб3.НайтиСтроки(Новый Структура("Группировка", сСтрока.Группировка));
	Рез3.Вставить(сГруппировка, Новый Массив);
	Для каждого сСтрока2 Из сМассивНайденных Цикл
		Рез3[сГруппировка].Добавить(сСтрока2.Значение);
	КонецЦикла;
КонецЦикла;
ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
Сообщить(СтрШаблон("Выборка Групп НайтиСтроки из индексированной таблицы: %1 сек.", ВремяЗамер));
Таб3 = Неопределено;
Рез3 = Неопределено;

Второй вариант проверялся с вариантами сортировки и индексации.

Таблица значений с помощью ГСЧ заполнялась текстовыми данными и копировалась для каждого теста.

Победил с двухкратным отрывом вариант 2 с индексацией без сортировки.

Способ обхода время выполнения, сек
Количество значений группировки 25% от количества строк 5% 25% 50%
Строк 100 1.000 10.000 100.000

100

1.000 10.000 100.000 100

1.000

10.000 100.000
Вариант 2 индексированная 0,001 0,013 0,141 1,599 0,001 0,014 0,141 1,581 0,001 0,014 0,142 1,558
Вариант 1 сортированная 0,002 0,018 0,220 3,320 0,001 0,016 0,224 3,251 0,001 0,020 0,217 3,334
Вариант 2 индексированная сортированная 0,001 0,023 0,258 3,999 0,001 0,020 0,255 3,800 0,002 0,019 0,265 3,898
Вариант 2         0,001 0,020 1,130 231,351 0,001 0,024 1,161 285,180
Вариант 2 сортированная         0,002 0,027 1,627 634,731 0,002 0,030 1,667 646,017

Прилагаю весь исходник:

Кратность=5;
МинСтрок = 10;
ЗначенийГруппировкиПроц = 25;
Таб = Новый ТаблицаЗначений;
Таб.Колонки.Добавить("Группировка", Новый ОписаниеТипов("Строка"));
Таб.Колонки.Добавить("Значение");
Для сКратность = 1 По Кратность Цикл
	сСтрок = Pow(10, сКратность);
	Сообщить(СтрШаблон("Таблица: %1 строк", сСтрок));
	сЗначГрупп = Цел(сСтрок/100*25);
	лГСЧ = Новый ГенераторСлучайныхЧисел();
	Для сНомерСтроки = 1 По сСтрок Цикл
		сНоваяСтрока = Таб.Добавить();
		сНоваяСтрока.Группировка = ЧислоПрописью(лГСЧ.СлучайноеЧисло(1, сЗначГрупп));
		сНоваяСтрока.Значение = ЧислоПрописью(лГСЧ.СлучайноеЧисло(1, 100000));
	КонецЦикла;
	
	Таб1 = Таб.Скопировать();
	Рез1 = Новый Соответствие();
	СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
	сГруппировка = "";
	Таб1.Сортировать("Группировка");
	Для каждого сСтрока Из Таб1 Цикл
		Если сСтрока.Группировка <> сГруппировка Тогда
			сГруппировка = сСтрока.Группировка;
			Рез1.Вставить(сГруппировка, Новый Массив);
		КонецЕсли;
		Рез1[сГруппировка].Добавить(сСтрока.Значение);
	КонецЦикла;
	ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
	Сообщить(СтрШаблон("Обход сортированной таблицы: %1 сек.", ВремяЗамер));
	Таб1 = Неопределено;
	Рез1 = Неопределено;
	
	Таб2 = Таб.Скопировать();
	Рез2 = Новый Соответствие();
	СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Группировки = Таб2.Скопировать(,"Группировка");
	Группировки.Свернуть("Группировка");
	Для каждого сСтрока Из Группировки Цикл
		сМассивНайденных = Таб2.НайтиСтроки(Новый Структура("Группировка", сСтрока.Группировка));
		Рез2.Вставить(сГруппировка, Новый Массив);
		Для каждого сСтрока2 Из сМассивНайденных Цикл
			Рез2[сГруппировка].Добавить(сСтрока2.Значение);
		КонецЦикла;
	КонецЦикла;
	ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
	Сообщить(СтрШаблон("Выборка Групп НайтиСтроки из неиндексированной таблицы: %1 сек.", ВремяЗамер));
	Таб2 = Неопределено;
	Рез2 = Неопределено;
	
	Таб3 = Таб.Скопировать();
	Рез3 = Новый Соответствие();
	СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Таб3.Индексы.Добавить("Группировка");
	Группировки = Таб3.Скопировать(,"Группировка");
	Группировки.Свернуть("Группировка");
	Для каждого сСтрока Из Группировки Цикл
		сМассивНайденных = Таб3.НайтиСтроки(Новый Структура("Группировка", сСтрока.Группировка));
		Рез3.Вставить(сГруппировка, Новый Массив);
		Для каждого сСтрока2 Из сМассивНайденных Цикл
			Рез3[сГруппировка].Добавить(сСтрока2.Значение);
		КонецЦикла;
	КонецЦикла;
	ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
	Сообщить(СтрШаблон("Выборка Групп НайтиСтроки из индексированной таблицы: %1 сек.", ВремяЗамер));
  Таб3 = Неопределено;
	Рез3 = Неопределено;
	
	Таб4 = Таб.Скопировать();
	Рез4 = Новый Соответствие();
	СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Таб4.Сортировать("Группировка");
	Группировки = Таб4.Скопировать(,"Группировка");
	Группировки.Свернуть("Группировка");
	Для каждого сСтрока Из Группировки Цикл
		сМассивНайденных = Таб4.НайтиСтроки(Новый Структура("Группировка", сСтрока.Группировка));
		Рез4.Вставить(сГруппировка, Новый Массив);
		Для каждого сСтрока2 Из сМассивНайденных Цикл
			Рез4[сГруппировка].Добавить(сСтрока2.Значение);
		КонецЦикла;
	КонецЦикла;
	ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
	Сообщить(СтрШаблон("Выборка Групп НайтиСтроки из неиндексированной сортированной таблицы: %1 сек.", ВремяЗамер));
	Таб4 = Неопределено;
	Рез4 = Неопределено;
	
	Таб5 = Таб.Скопировать();
	Рез5 = Новый Соответствие();
	СтартЗамер = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Таб5.Сортировать("Группировка");
	Таб5.Индексы.Добавить("Группировка");
	Группировки = Таб5.Скопировать(,"Группировка");
	Группировки.Свернуть("Группировка");
	Для каждого сСтрока Из Группировки Цикл
		сМассивНайденных = Таб5.НайтиСтроки(Новый Структура("Группировка", сСтрока.Группировка));
		Рез5.Вставить(сГруппировка, Новый Массив);
		Для каждого сСтрока2 Из сМассивНайденных Цикл
			Рез5[сГруппировка].Добавить(сСтрока2.Значение);
		КонецЦикла;
	КонецЦикла;
	ВремяЗамер = (ТекущаяУниверсальнаяДатаВМиллисекундах() - СтартЗамер)/1000;
	Сообщить(СтрШаблон("Выборка Групп НайтиСтроки из сортированной, индексированной  таблицы: %1 сек.", ВремяЗамер));
	Таб5 = Неопределено;
	Рез5 = Неопределено;
КонецЦикла;

 

Проверено на следующих конфигурациях и релизах:

  • Бухгалтерия предприятия, редакция 3.0, релизы 3.0.181.10

Вступайте в нашу телеграмм-группу Инфостарт

ТаблицаЗначений Производительность

См. также

Математика и алгоритмы Программист 1С:ERP Управление предприятием 2 Абонемент ($m)

Данная внешняя обработка для платформы 1С:Предприятие реализует усовершенствованный алгоритм Левенштейна для вычисления схожести строк с учетом различных лингвистических особенностей русского языка. В отличие от классической реализации, этот алгоритм учитывает фонетические, визуальные и контекстные особенности набора текста.

1 стартмани

07.11.2025    3807    11    InFlach    17    

25

Математика и алгоритмы Программист 1C v8.2 1C:Бухгалтерия Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    12297    stopa85    12    

42

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    19403    user1959478    57    

39

Математика и алгоритмы Разное 1С v8.3 1C:Бухгалтерия Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    11763    maksa2005    8    

27

Математика и алгоритмы Инструментарий разработчика Программист 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    19554    11    SpaceOfMyHead    20    

64

Математика и алгоритмы Программист 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    13237    RustIG    9    

30

Механизмы платформы 1С Математика и алгоритмы Программист 1С v8.3 Россия Бесплатно (free)

В статье анализируются средства платформы для решения системы линейных уравнений в 1С. Приводятся доводы в пользу некорректной работы встроенных алгоритмов, а значит потенциально некорректного расчета себестоимости в типовых конфигурациях.

23.11.2022    12354    gzharkoj    15    

27

Математика и алгоритмы Программист 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    11435    8    kalyaka    11    

45
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. n_mezentsev 65 13.09.25 09:34 Сейчас в теме
Не знал, что таблицы значений поддерживают индексирование, думал, это прерогатива запросов. Спасибо за ваш труд!
P.S. Как-то сравнивал метод НайтиСтроки с загрузкой ТЗ в запрос с дальнейшим обходом по группировке. НайтиСтроки победил однозначно! А тут еще и индексирование. Это ж структурированная таблица - класс!
Для отправки сообщения требуется регистрация/авторизация