Имя: Пароль:
1C
1С v8
Оптимизация кода XML через XDTO в табличную часть
,
0 jedbez
 
20.12.17
01:28
Есть получаемый XML определенного формата, в XDTO описан. После происходит преобразование параметров в значения справочников по уеазанным кодам.

// XML в ОбъектXDTO
ЧтениеXML.УстановитьСтроку(XMLСтрока);
Об = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,Тип_);
// SLUCH - табличная часть документа
НС = Объект.SLUCH.Добавить();
Для Каждого Эл из Об.SLUCH[0].Свойства() цикл
    ЗаполнитьПоле(НС[Эл.Имя],Об.SLUCH[0][Эл.Имя],,"SLUCH ");
КонецЦикла;

Ну и непосредственно сама процедура, определяет какой тип имеет поле в строке табличной части и ищет в справочнике
Процедура ЗаполнитьПоле(Поле,Значение,РазрешитьДобавить=Ложь,Коментарий="")
    
    Если Значение<>Неопределено тогда
        Если ТипЗнч(Поле)=Тип("Строка") тогда
            Поле = Значение;
        ИначеЕсли ТипЗнч(Поле)=Тип("Число") тогда
            Поле = Значение;
        ИначеЕсли ТипЗнч(Поле)=Тип("Дата") тогда
            Поле = Значение;
        ИначеЕсли ТипЗнч(Поле)=Тип("Булево") тогда
            Поле = Значение;
        ИначеЕсли ТипЗнч(Поле)=Тип("Null") тогда
            Поле = Значение;
        Иначе
            Мд = Метаданные.НайтиПоТипу(ТипЗнч(Поле));
            Спр = Справочники[МД.Имя];
            Если СокрЛП(Значение) <> "" тогда
                Если ТипЗнч(Поле.Код)=Тип("Строка") тогда
                    Поле = Спр.НайтиПоКоду(Строка(Значение));
                ИначеЕсли ТипЗнч(Поле.Код)=Тип("Число") тогда
                    Попытка
                        Поле = Спр.НайтиПоКоду(Число(Значение));
                    Исключение
                    КонецПопытки;
                КонецЕсли;
            КонецЕсли;
            Если ЗначениеЗаполнено(Значение) и Поле = Спр.ПустаяСсылка() тогда
                НС = Ошибки.Добавить();
                НС.Описание = ""+Коментарий+" - "+МД.Имя+" <> "+Значение;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Всё работает нормально, но записей очень много, и вот понимаю что можно както оптимизировать, ускорить разбор или ускорить преобразование строки XML с кодами справочников в значения полей строки табличной части докумета
1 France
 
20.12.17
01:31
"..много.." - а насколько много??
2 Armando
 
20.12.17
01:44
Покажи снимок экрана с результатами замера производительности в отладчике.
3 jedbez
 
20.12.17
10:12
Во, замером производительности научился пользоваться...

[img]http://s014.radikal.ru/i328/1712/3c/d8f8b9787f3c.png[/img]

Много это около 221-370 сек.
разбор 6700 строк
4 jedbez
 
20.12.17
10:13
5 jedbez
 
20.12.17
10:25
Не видно первых строк
http://s017.radikal.ru/i420/1712/e7/0e39b7805546.png

Вот 2,3 строка

Поле = Спр.НайтиПоКоду(Строка(Значение));

из функции "ЗаполнитьПоле" - всё сжирают
6 Armando
 
20.12.17
15:11
Вот с этим и надо что-то делать. НайтиПоКоду это обращение к СУБД. По возможности коды надо предварительно закэшировать, например, в соответствие.
7 тарам пам пам
 
20.12.17
15:29
(5) сначала считывай в массив все коды сразу, потом вытаскивай из БД одним запросом все нужные ссылки, потом подставляй уже в таблицу - будет быстро.
8 kiruha
 
20.12.17
15:33
(5)
Не пиши так никогда
9 jedbez
 
21.12.17
02:03
(6) В табличной строке порядка 40 ссылок на различные справочники, хэшировать все справочники, это же не логично, хотя можно попробовать.
А запросом не быстрее будит, чем НайтиПоКоду?
(7) Хм... надо попробовать

Мысль такая, для каждого поля сделать соответствие в которое поместить Структуру (Ключ, ссылка) возможных значений поля.
И при заполнении строки таблицы, дёргать от туда ссылки на справочники, согласно кода из XML.

(8) Критикуя - предлагай, иначе остаётся вопрос - Чо? (Выражающий не аргументированный позыв к агрессивному диалогу ни о чём, троль?)
10 RomaH
 
naïve
21.12.17
06:54
(9) как вариант кеширования - общий модуль с повторным использованием
но кещирование поможет если много совпадающих кодов
11 тарам пам пам
 
21.12.17
09:28
(9) "А запросом не быстрее будит" - запросом в цикле будет ровно то же самое, что и НайтиПоКоду в цикле, потому что НайтиПоКоду и есть запрос.

Поэтому для ускорения нужно делать меньше запросов => читаешь сначала все коды (либо, если будут проблемы с недостатком памяти при загрузке очень большого файла, часть кодов; 6700 строк - маленький файл, если что) и ищешь сразу все ссылки.
12 kiruha
 
21.12.17
12:37
(9)
>>ритикуя - предлагай, иначе остаётся вопрос - Чо? (Выражающий не аргументированный позыв к агрессивному диалогу ни о чём, троль?)

Раз не было - код настолько плох , что даже нет смысла объяснять - на курсы вам надо , а не темы писать
13 jedbez
 
26.12.17
05:41
(12) В чём код плох? "Нет смысла объяснять", а вы попробуйте. Млин, всё равно не пойму я вас, будьте добры спуститесь с небес до моего уровня и ткните презренного меня в чем плохость кода, или это просто вброс для накручивания счетчика сообщений?
14 NWsFF
 
26.12.17
06:43
(13) Забей для 1С хороший код :)
15 h-sp
 
26.12.17
07:41
(13) вот это

            Мд = Метаданные.НайтиПоТипу(ТипЗнч(Поле));
            Спр = Справочники[МД.Имя];

что-то дикость какая-то

напишите

            Мд = Поле.Метеданные();
            Спр = Справочники[МД.Имя];
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой