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

01.09.25

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

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

Бесплатные

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

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

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

Вариант 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

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

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

См. также

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

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

1 стартмани

30.01.2024    10605    stopa85    12    

42

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

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

19.10.2023    17210    user1959478    57    

39

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

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

2 стартмани

29.09.2023    10136    maksa2005    8    

27

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

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

1 стартмани

09.06.2023    17847    11    SpaceOfMyHead    20    

63

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

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

03.04.2023    11643    RustIG    9    

30

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

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

23.11.2022    10699    gzharkoj    15    

26

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

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

1 стартмани

21.03.2022    10803    8    kalyaka    11    

45

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

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    12851    fishca    12    

39
Для отправки сообщения требуется регистрация/авторизация