Имя: Пароль:
1C
1С v8
Наилучший тип данных для хеш-таблицы на 10'000 элементов
0 wisekat
 
20.09.12
15:29
Задача такая. Надо загрузить из Excel-я список соответствий инвентарных номеров ОС и кодов их подразделений, а затем многократно обращаться к этому списку и находить быстро по инв.номеру код подразделения.

Какую оптимальную технику с точки зрения скорости следует использовать?

Руки чешутся взять структуру и использовать инв. номера как поля, но как себя поведёт структура на 10000 записях? Сейчас буду пробовать...

Можно ещё таблицу значений с индексом, но по идее это должно медленее работать.

Есть ещё варианты?
1 Rovan
 
гуру
20.09.12
15:30
(0) Соответствие
2 unregistered
 
20.09.12
15:33
(0) >>  находить быстро по инв.номеру код подразделения.

Потом небось получив код подразделения ищешь ссылку на элемент справочника Подразделения по этому коду?

Если так, то решение вообще неоптимальное.
3 wisekat
 
20.09.12
15:42
(2) Да, мысль сразу найти подразделение тоже была, но так не получится - подразделение зависит от внешнего окружения (перебираем документы по филиалам, у них подчинённые подразделения, так что один и тот же код подразделения будет указывать на разные подразделения для разных филиалов).
4 wisekat
 
20.09.12
15:43
(1) Соответствие хуже, т.к. оно берёт как ключи объекты разных типов. У меня же строки в качестве поля вполне достаточно для инв. номера.
5 Reset
 
20.09.12
15:44
(0) В Соответствии самый быстрый поиск
6 Reset
 
20.09.12
15:45
Индексированная таблица чуть (минимально) медленней.
Остальные варианты сильно отстают
7 НЕА123
 
20.09.12
15:46
(4)
> Соответствие хуже, т.к. оно берёт как ключи объекты разных типов.
интересная логика.
8 ILM
 
гуру
20.09.12
15:49
(0) Соответствие - лучше всего.
Варианты:
Структура.
Массив.
ТЗ.
9 НЕА123
 
20.09.12
15:51
(6)
индекс у ТЗ наверняка оптимальнее, чем у Соответствие.
а на практике? кто ж лидер.
10 wisekat
 
20.09.12
15:55
(9) Вопрос построения индекса и хеш-таблицы.
Я ещё и в .NET программирую, так там хеш-таблица для такого случая, пожалуй, самое оптимальное решение.
Хотелось бы знать как оно в 1С внутри...
11 Reset
 
20.09.12
15:56
(9) -> (5)
Конкретный же выбор коллекции для конктретного случая зависит от ситуации, тз универсальнее в использовании

Подробно изъясняться в 100й раз лень
12 Reset
 
20.09.12
15:57
(10) Лучше делом займись чем искать оптимальное решение, отличающееся на 0.00001 сек
13 Liova
 
20.09.12
15:58
Мне кажется, что использовать - соответствие или ТЗ с индексом не слишком принципиально, быстрее уже бы и так и так сделать и сравнить скорость. А потом искать то, где действительно нужна оптимизация.
14 vmv
 
20.09.12
16:01
РС с двумя измерениями сделай и баста, даже если задача разовая то попахивает авантюрой грузить в память стандартные коллецци от 10К строк и потом юзать в них поиск циклом.

А так грузанул в простейший РС 100500 пар ИнвНомерКод,ПодрКод

и юзай в той же обработке возможно уже запросом получая все что нужно без глупых поисков и итераций - 1С вам не гуглятина!

Потом РС грохаешь, а если задача периодическая оставляешь

ВСЕ остальное от лукавого
15 unregistered
 
20.09.12
16:02
(3) получив таблицу можно запихнуть её в запрос и там получить всё что тебе нужно.

При более или менее значительном размере таблицы это будет быстрее, чем любые переборы в циклах.
16 Axel2009
 
20.09.12
16:06
(15) да гнать на сервер СУБД через сервер 1с 500тыс строк конечно круче, чем 1 раз проанализировать на клиенте. харашо придумал
17 vmv
 
20.09.12
16:08
(16) согласен, сувать в параметры запроса массивные тз - расстрел
18 vde69
 
20.09.12
16:09
19 ILM
 
гуру
20.09.12
16:12
Соответствие - как кэш, самое то.
Если многоразовый нужен, то регистр сведений.
20 unregistered
 
20.09.12
16:23
(16) >>  гнать на сервер СУБД через сервер 1с 500тыс строк конечно круче, чем 1 раз проанализировать на клиенте

Скорее всего круче. Особенно учитывая (3): "перебираем документы по филиалам, у них подчинённые подразделения".

Конечно многое зависит от алгоритма и реального объема данных, но если правильно построить один запрос, который будет и документы перебирать и подчиненные подразделения по филиалам, будет работать однозначно быстрее, чем тянуть все эти данные (документы и подчиненные подразделения) по 500-стам тысячам строк с сервера на клиента, перебирая в цикле.
21 wisekat
 
20.09.12
16:28
Так, ребята - извините за молчание - как раз кодил.
СООТВЕТСТВИЕ СРАБОТАЛО НА УРА. 9800 записей влетают туда на раз-два, и потом практически мгновенно идёт поиск нужной "записи".
22 wisekat
 
20.09.12
16:30
Блин, ошибся - я же СТРУКТУРУ взял :)

Экспериментировать с ТЗ уже не буду - для моей задачи структуры вполне хватает, и скорость очень даже приемлема.

Если кто с ТЗ сравнит - отпишитесь плиз о результатах.
23 wisekat
 
20.09.12
16:33
(12) Вот я так и подумал - не вижу принципиальной разницы между структурой и ТЗ. Ни в кодировании, ни во времени. Хотя нет, структуру чуть легче в коде заваять :)
24 Нуф-Нуф
 
20.09.12
16:33
v8: Что быстрее? Поиск в таблице значений, соответствии или прямой поиск в базе?

еще есть такая штука как общий модуль с хешированием
25 wisekat
 
20.09.12
16:35
(14) Идея с РС - классная, но есть одно "НО"!
Делается обработка для "стороннего" заказчика, у которого нельзя менять конфу.

А так РС - это "вери гуд". Даже для отладки. Сейчас относительно много времени уходит на загрузку одного и того же файла, а так сделал раз РС - и всё, юзай.
26 fisher
 
20.09.12
16:35
(23) Есть подозрение (ничем не подкрепленное), что структура быстрее индексированной ТЗ.
27 wisekat
 
20.09.12
16:37
(24) Ощий модуль с кешированием - тоже хорошо, но у меня в процессе жизни обработки запрос по одному инв. номеру делается только один раз, т.е. кеш как таковой не будет использован.
28 Liova
 
20.09.12
17:06
(25) загрузка из экселя 10000 строк делается одной строкой и моментом. У тебя перебор ячеек?
29 Axel2009
 
20.09.12
17:19
(28) расскажи
30 vde69
 
20.09.12
17:33
(29) ексель может использоватся прямо в запросе как внений источник данных, но есть тонкости, я не советую :)
31 acsent
 
20.09.12
17:38
(30) а внешние источники можно без конфигуратора описывать?
32 Axel2009
 
20.09.12
17:40
(30) я про эти "тонкости" драйвера знаю
33 3Jl0
 
20.09.12
17:40
(1) тут ответ. структура сереть.
34 Liova
 
20.09.12
17:42
(29)

Функция ЗагрузитьЭксельВМассив(Excel)
   
   
   Ячейка1 = Excel.Sheets(1).Cells(1,1);
   Ячейка2 = Excel.Sheets(1).Cells(Excel.Sheets(1).UsedRange.Rows.Count+1, Excel.Sheets(1).UsedRange.Columns.Count+1);
   Массив = Excel.Sheets(1).Range(Ячейка1, Ячейка2).Value.Выгрузить();
   
   
   Возврат Массив;
КонецФункции
35 Axel2009
 
20.09.12
17:44
(34) мм, спасибо, посмотрю
36 Axel2009
 
20.09.12
17:45
(34)+ в догонку, а форматы воспринимаются нормально? либо там только значение хранится
37 Liova
 
20.09.12
17:47
(36) .Value - только значение, мне хватало
Всех хитростей не знаю, но .Text использовать нельзя ни в коем случае, там если ширины колонки не будет хватать будет "#######".
38 Axel2009
 
20.09.12
18:00
(37) ясно. 1с делает выгрузку некоторых значений через формат ячейки, а Value там хранится отличное от отображаемого.
но на будущее буду знать.
39 3Jl0
 
20.09.12
18:10
не читал. (0) но загружаем сначала в тз. потом тз это врем таблица в запросе. дальше понятно
40 3Jl0
 
20.09.12
18:11
Процедура Загрузить() Экспорт
       ExcelФайл = ПолучитьCOMОбъект(мВыбФайл);
       Состояние("Обработка файла Microsoft Excel...");
       // Читаем данные первого листа книги
       Попытка
           ExcelЛист = ExcelФайл.Sheets(1);        
       Исключение
           Предупреждение("Файл открыт, закройте его!!!",,"ОШИБКА");
           Возврат;
       КонецПопытки;
       //
       RowCount     = 6500;
       ВсегоКолонок = 3;
       НомерПервойКолонки = 1;
       //
       СоздатьТЧДанных();
       //Обратаем всю область данных
           Область = ExcelЛист.Range(ExcelЛист.Cells(1,НомерПервойКолонки), ExcelЛист.Cells(RowCount,ВсегоКолонок));
           Данные = Область.Value.Выгрузить();        
       //Создание пустых строк по RowCount    
       Для Счетчик = 1 По RowCount Цикл
           НоваяСтрока = ТЧДанных.Добавить();
       КонецЦикла;
       
       //Заполнение Тч данными
       Для Счетчик = 0 По ВсегоКолонок-1 Цикл
           ТЧДанных.ЗагрузитьКолонку(Данные[Счетчик], "Колонка"+Счетчик);
       КонецЦикла;
       Создать();
       ExcelФайл.Close();
КонецПроцедуры
41 3Jl0
 
20.09.12
18:12
в open  не так... так что думай
42 fisher
 
20.09.12
18:59
(30) А что за тонкости? Как-то раз юзал ради прикола, заметил только что последнюю строку нормально не определяет (выборку до победы открывает) и с лист вроде надо явно указывать, а там тоже ньюансы могут быть.
А еще какие подводные камни?
43 Axel2009
 
21.09.12
09:35
(42) "Проблема в структуре данных листа который вы пытаетесь прочитать. Конкретно - из-за ячейки G7, которая содержит дату.
Т.к. она идёт первой в колонке, она оверрайдит смешанный режим чтения, поэтому все строки под ней будут интерпретированы как NULL. Тащемто эт известный глюк, можете погуглить."
файл не буду приводить..
44 wisekat
 
21.09.12
16:14
(28) (30) Да в структуру отлично всё традиционным перебором загружается, никаких проблем с форматами.
И нафига мне массив, если мне как раз и нужна была структура как хеш-таблица для очень быстрого поиска по ключу -инвентарному номеру?
Уже отошли от первоначальной постановки задачи.
45 stix2010
 
21.09.12
16:28
хы, есть еще люди читающие xls через com объект exel?
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс