|
Оптимизация поиска в коллекциях значений | ☑ | ||
---|---|---|---|---|
0
drugoimir
19.07.17
✎
11:32
|
Добрый день.
Нужно оптимизировать алгоритм, может кто-то натолкнет на верную мысль. Алгоритм взят из упп при расчете себестоимости. Итак: 1) Есть Структура (тип структура) состояний, она инициализируется динамически до цикла. В нее добавляются имена ключей поиска для дальнейшего сравнения. Назовем ее СтруктураСостояний 2) Есть Соответствие (тип соответствие) параметров состояний параметров состояний. Ключом идет индекс состояния, а значением структура значений для этого состояния (ключи в этой структуре всегда совпадают со структурой ключей из п.1). назовем ее Соответствие Параметров 3) Есть ТЗ, колонки в которой в том числе состоят из ключей стр п.1, но всего их больше, есть и другие колонки с именами "Сумма, количество" и т.п. Далее идет примерно такой код: Для Каждого Строка Из Таб Цикл // поиск выплняется полным перебором // Состояния-источники // Найдем состояние в соответсвии НайденоСостояние=Ложь; Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл НайденоСостояние=Истина; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница"или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда НайденоСостояние = Ложь; // состояния различны Прервать; // дальше можно не проверять КонецЕсли; КонецЦикла; Если НайденоСостояние Тогда Прервать; КонецЕсли; КонецЦикла; Получается что для каждого ключа из структура п.1 идет перебор и сравнения соотв. по этому ключу со строкой ТЗ. |
|||
1
aleks_default
19.07.17
✎
12:58
|
НайденоСостояние = Таб.НайтиСтроки(ЭлементСостояние.Значение).Количество()>0
|
|||
2
mistеr
19.07.17
✎
13:22
|
(0) Приведенный код это фактически соединение двух таблиц, хоть одна из них и в форме Соответствия.
Соответственно (каламбур невольный), первая мысль это перенести соединение в запрос. Если это невозможно или нецелесообразно, пойдем дальше. Какого размера обычно бывают наборы входных данных (ТЗ и Соответствие)? |
|||
3
drugoimir
19.07.17
✎
14:06
|
(0)(1) Так сделать нельзя, т.к. Поиск фактически идет в СоотвПараметровСостояний , которое заполняется в цикле. Лучше тогда приведу код цикла полностью:
Для Каждого Строка Из Таб Цикл // поиск выплняется полным перебором // Состояния-источники // Найдем состояние в соответсвии НайденоСостояние=Ложь; Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл НайденоСостояние=Истина; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда НайденоСостояние = Ложь; // состояния различны Прервать; // дальше можно не проверять КонецЕсли; КонецЦикла; Если НайденоСостояние Тогда Прервать; КонецЕсли; КонецЦикла; Если НайденоСостояние Тогда ИндексСостояния = ЭлементСостояние.Ключ; Иначе // Переносим в соответствие СтрСост = Новый Структура; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]); КонецЦикла; ИндексСостояния = СоотвПараметровСостояний.Количество(); СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); КонецЕсли; // Оставим в таблице ссылку на состояние Строка.Источник = ИндексСостояния; // То же самое для состояний-приемников // Найдем состояние в соответсвии НайденоСостояние=Ложь; Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл НайденоСостояние=Истина; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]) Тогда НайденоСостояние = Ложь; // состояния различны Прервать; // дальше можно не проверять КонецЕсли; КонецЦикла; Если НайденоСостояние Тогда Прервать; КонецЕсли; КонецЦикла; Если НайденоСостояние Тогда ИндексСостояния = ЭлементСостояние.Ключ; Иначе // Переносим в соответствие СтрСост = Новый Структура; Для Каждого Элемент Из СтруктураСостояния Цикл СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]); КонецЦикла; ИндексСостояния = СоотвПараметровСостояний.Количество(); СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); КонецЕсли; // Оставим в таблице ссылку на состояние Строка.Приемник = ИндексСостояния; КонецЦикла; Я так понял лучше всего соответствие СоотвПараметровСостояний развернуть в Таблицу значений, сделать составной индекс и внутри нее производить поиск. |
|||
4
МихаилМ
19.07.17
✎
14:09
|
(3)
зависит от типов данных для простых типов (дата,строка,число,булево) соответствие работает быстрее. |
|||
5
drugoimir
19.07.17
✎
14:15
|
(4) По текущему алгоритму получается, что мы перебираем соответствие. Для каждой его строки мы анализируем значение соответствия(структуру) по дин. ключу состояние (структура СтруктураСостояний тут тоже перебор) и сравниваем найденное значение структуры со строкой ТЗ Таб, где значение отбирается по этому же дин. ключу состояние
Т.е. прямого поиска в соответствии нет. Есть поиска по структуре, которая внутри него по дин. ключу. |
|||
6
H A D G E H O G s
19.07.17
✎
14:23
|
(0) Дичь какая
|
|||
7
H A D G E H O G s
19.07.17
✎
14:25
|
Если в 2 и более таблицах данных ПОСТОЯННО много и хочется вывести производительность в идеал и получить батхерт от наследника - напиши свой mergejoin
|
|||
8
H A D G E H O G s
19.07.17
✎
14:30
|
Таблица1.Сортировать("КлючПоиска");
Таблица2.Сортировать("КлючПоиска"); Счетчик1=0; Счетчик2=0; Пока Истина Цикл СтрокаТаблицы1=Таблица1[Счетчик1]; СтрокаТаблицы2=Таблица2[Счетчик2]; Если СтрокаТаблицы1.КлючПоиска>СтрокаТаблицы2.КлючПоиска Тогда Счетчик2=Счетчик2+1; ИначеЕсли СтрокаТаблицы1.КлючПоиска<СтрокаТаблицы2.КлючПоиска Тогда Счетчик1=Счетчик1+1; Иначе СтрокаТаблицы1.ЗначениеИзТаблицы2=СтрокаТаблицы2.Значение; КонецЕсли; Если Счетчик1>=Таблица1.Количество() или четчик2>=Таблица2.Количество() Тогда Прервать; КонецЕсли; КонецЦикла; Как то так |
|||
9
H A D G E H O G s
19.07.17
✎
14:31
|
(8) Ну и там граничные условия на заполненость таблиц
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |