Сколько себя помню, всегда, когда мне нужно было конвертировать соответствие в структуру, я использовал цикл, в котором наполнял структуру.
Результат = Новый Структура;
Для Каждого текЭлемент Из ЯСоответствие Цикл
Результат.Вставить(текЭлемент.Ключ, текЭлемент.Значение);
КонецЦикла;
Уверен, что это самый популярный вариант. Конечно, нужно быть уверенным, что в ключах нет запрещенных символов, которые не сможет переварить структура. Вообще примеров конвертации может быть очень много. Но...
Когда-то давно мне пришел в голову другой способ, который использует JSON преобразование, и только на этой неделе пришла мысль в голову, все замерить.
В замере буду использовать еще два странных варианта и вариант через ЗначениеВСтрокуВнутр (этот способ мне подсказали в Телеграм канале e1c_community). Также буду использовать вариант через JSON и XML (этот способ отсутствовал в первоначальной версии статьи, он громоздкий и содержит много замен строк).
Озвученные варианты:
Запрос = Новый Запрос;
Для Каждого текЭлемент Из ЯСоответствие Цикл
Запрос.УстановитьПараметр(текЭлемент.Ключ, текЭлемент.Значение);
КонецЦикла;
Результат = Запрос.Параметры;
НастройкиКомпоновкиДанных = Новый НастройкиКомпоновкиДанных;
Для Каждого текЭлемент Из ЯСоответствие Цикл
НастройкиКомпоновкиДанных.ДополнительныеСвойства.Вставить(текЭлемент.Ключ, текЭлемент.Значение);
КонецЦикла;
Результат = НастройкиКомпоновкиДанных.ДополнительныеСвойства;
Или
НастройкиКомпоновкиДанных = Новый НастройкиКомпоновкиДанных;
Результат = НастройкиКомпоновкиДанных.ДополнительныеСвойства;
Для Каждого текЭлемент Из ЯСоответствие Цикл
Результат.Вставить(текЭлемент.Ключ, текЭлемент.Значение);
КонецЦикла;
Строка = ЗначениеВСтрокуВнутр(ЯСоответствие);
СтрокаМод = СтрЗаменить(Строка, "3d48feae-a9c6-4c5a-a099-9eb6477630c6", "4238019d-7e49-4fc9-91db-b6b951d5cf8e");
Результат = ЗначениеИзСтрокиВнутр(СтрокаМод);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ЯСоответствие);
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ЗаписьJSON.Закрыть());
Результат = ПрочитатьJSON(ЧтениеJSON);
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЯСоответствие);
РезультатMAP = ЗаписьXML.Закрыть();
РезультатMAP = СтрЗаменить(РезультатMAP,"<Map","<Structure");
РезультатMAP = СтрЗаменить(РезультатMAP,"</Map>","</Structure>");
РезультатMAP = СтрЗаменить(РезультатMAP,"<pair>","");
РезультатMAP = СтрЗаменить(РезультатMAP,"</pair>","</Property>");
РезультатMAP = СтрЗаменить(РезультатMAP,"<Key xsi:type=""xs:string"">","<Property name=""");
РезультатMAP = СтрЗаменить(РезультатMAP,"</Key>",""">");
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(РезультатMAP);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
Какие замеры я решил проделать?
1 Сформировать небольшое соответствие из 10 элементов. В цикле в несколько повторений провести преобразование. Замерять только работу в цикле. Повторений будет 1, 1000 и 10000.
2 Сформировать среднее соответствие из 1000 элементов. В цикле в несколько повторений провести преобразование. Замерять только работу в цикле. Повторений будет 1 и 1000.
3 Сформировать большое соответствие из 10000 элементов. В цикле в несколько повторений провести преобразование. Замерять только работу в цикле. Повторений будет 1 и 100.
- Во всех замерах, буду включать debug, а затем выключать.
- Соответствие формирую разово и наполняю его в зависимости от указанного количества элементов.
Функция СформироватьСоответствиеСМокДанными(КоличествоЭлементов = 1)
Результат = Новый Соответствие;
ШаблонКлюча = "Эл%1";
Для счетчик = 1 По КоличествоЭлементов Цикл
Результат.Вставить(СтрШаблон(ШаблонКлюча,Формат(счетчик,"ЧН=0; ЧГ=")),?(счетчик % 2 > 0,Формат(счетчик,"ЧН=0; ЧГ="),счетчик));
КонецЦикла;
Возврат Результат;
КонецФункции
Формирую соответствие, в котором в ключ элемента будет писаться "Эл1", "Эл2"..."ЭлХ". В значение "1", 2, "3", 4, "5" и т.д
Замер 1-1 (Соответствие 10 элементов, 1 повторение)
[Debug включен]
- Запрос :0мс.
- НастройкиКомпоновкиДанных :0мс.
- Структура :0мс.
- ЗначениеВСтроку :0мс.
- XML :0мс.
- JSON :0мс.
[Debug выключен]
- Запрос :0мс.
- НастройкиКомпоновкиДанных :0мс.
- Структура :0мс.
- ЗначениеВСтроку :0мс.
- НастройкиКомпоновкиДанныхВ2 :0мс.
- JSON :0мс.
- XML :1мс.
На глаз победителя выявить не удалось, и я запустил с замером и получил самые тяжелые операции:
- СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
- СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЯСоответствие);
- НастройкиКомпоновкиДанных = Новый НастройкиКомпоновкиДанных;
При следующих замерах будет уже более показательно.
Замер 1-2 (Соответствие 10 элементов, 1000 повторений)
[Debug включен]
- JSON :43мс.
- ЗначениеВСтроку :46мс.
- Структура :70мс.
- Запрос :115мс.
- НастройкиКомпоновкиДанных :123мс.
- XML :332мс.
[Debug выключен]
- Структура :19мс.
- JSON :22мс.
- Запрос :24мс.
- ЗначениеВСтроку :42мс.
- НастройкиКомпоновкиДанных :53мс.
- НастройкиКомпоновкиДанныхВ2 :53мс.
- XML :315мс.
Обратите внимание метод через JSON вырвался вперед при включенном debug. Почти в два раза быстрее того метода, который я использую повсеместно... Что будет дальше?
Замер 1-3 (Соответствие 10 элементов, 10000 повторений)
[Debug включен]
- JSON :318мс.
- ЗначениеВСтроку :538мс.
- Структура :622мс.
- Запрос :733мс.
- НастройкиКомпоновкиДанных :1093мс.
- XML :3366мс.
[Debug выключен]
- Структура :188мс.
- JSON :228мс.
- Запрос :313мс.
- ЗначениеВСтроку :474мс.
- НастройкиКомпоновкиДанныхВ2 :523мс.
- НастройкиКомпоновкиДанных :732мс.
- XML :3602мс.
Метод через JSON просто разорвал конкурентов cо включенным debug, но и вариант ЗначениеВСтроку выглядит интересно. С выключенным debug метод используемый мной повсеместно показал лучший результат.
Теперь увеличим количество элементов в соответствии и замерим.
Замер 2-1 (Соответствие 1000 элементов, 1 повторение)
[Debug включен]
- JSON :2мс.
- ЗначениеВСтроку :3мс.
- Запрос :6мс.
- НастройкиКомпоновкиДанных :6мс.
- Структура :7мс.
- XML :23мс.
[Debug выключен]
- JSON :1мс.
- Структура :2мс.
- НастройкиКомпоновкиДанных :2мс.
- ЗначениеВСтроку :2мс.
- НастройкиКомпоновкиДанныхВ2 :2мс.
- Запрос :3мс.
- XML :20мс.
Уже на старте JSON и ЗначениеВСтроку идут в отрыв при включенном debug.
Топ операции:
- Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
- СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЯСоответствие);
- НастройкиКомпоновкиДанных.ДополнительныеСвойства.Вставить(текЭлемент.Ключ, текЭлемент.Значение);
- Каждого текЭлемент Из ЯСоответствие Цикл
Замер 2-2 (Соответствие 1000 элементов, 1000 повторений)
[Debug включен]
- JSON :1433мс.
- ЗначениеВСтроку :2457мс.
- Структура :5915мс.
- Запрос :6384мс.
- НастройкиКомпоновкиДанных :6392мс.
- XML :28048мс.
[Debug выключен]
- JSON :1206мс.
- Структура :1629мс.
- Запрос :2071мс.
- НастройкиКомпоновкиДанных :2094мс.
- ЗначениеВСтроку :2264мс.
- НастройкиКомпоновкиДанныхВ2 :2367мс.
- XML :23069мс.
Картина, по-моему, уже ясна.
Еще увеличим количество элементов в соответствии и замерим.
Замер 3-1 (Соответствие 10000 элементов, 1 повторение)
[Debug включен]
- JSON :15мс.
- ЗначениеВСтроку :25мс.
- Структура :63мс.
- НастройкиКомпоновкиДанных :65мс.
- Запрос :66мс.
- XML :232мс.
[Debug выключен]
- JSON :13мс.
- Структура :18мс.
- НастройкиКомпоновкиДанных :20мс.
- Запрос :21мс.
- НастройкиКомпоновкиДанныхВ2 :22мс.
- ЗначениеВСтроку :23мс.
- XML :228мс.
Топ операций:
- Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
- СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЯСоответствие);
- Запрос.УстановитьПараметр(текЭлемент.Ключ, текЭлемент.Значение);
- НастройкиКомпоновкиДанных.ДополнительныеСвойства.Вставить(текЭлемент.Ключ, текЭлемент.Значение);
- Каждого текЭлемент Из ЯСоответствие Цикл
Замер 3-2 (Соответствие 10000 элементов, 100 повторений)
[Debug включен]
- JSON :1883мс.
- ЗначениеВСтроку :2931мс.
- Структура :6594мс.
- Запрос :7242мс.
- НастройкиКомпоновкиДанных :7354мс.
- XML :26675мс.
[Debug выключен]
- JSON :1542мс.
- Структура :2223мс.
- Запрос :2250мс.
- НастройкиКомпоновкиДанныхВ2 :2538мс.
- НастройкиКомпоновкиДанных :2649мс.
- ЗначениеВСтроку :2810мс.
- XML :23086мс.
Вид замера со включенным debug | 10 элем. 1 цикл |
10 элем. 1000 циклов |
10 элем. 10000 циклов |
1000 элем. 1 цикл |
1000 элем. 1000 циклов |
10000 элем. 1 цикл |
1000 элем. 100 циклов |
JSON | 0мс | 43мс | 318мс | 2мс | 1433мс | 15мс | 1883мс |
Структура | 0мс | 70мс | 622мс | 7мс | 5915мс | 63мс | 6594мс |
Запрос | 0мс | 115мс | 733мс | 6мс | 6384мс | 66мс | 7242мс |
Настройки Компоновки Данных | 0мс | 123мс | 1093мс | 6мс | 6392мс | 65мс | 7354мс |
ЗначениеВСтроку | 0мс | 46мс | 538мс | 3мс | 2457мс | 25мс | 2931мс |
XML | 0мс | 332мс | 3366мс | 23мс | 28048мс | 232мс | 26675мс |
Вид замера с выключенным debug | 10 элем. 1 цикл |
10 элем. 1000 циклов |
10 элем. 10000 циклов |
1000 элем. 1 цикл |
1000 элем. 1000 циклов |
10000 элем. 1 цикл |
1000 элем. 100 циклов |
JSON | 0мс | 22мс | 228мс | 1мс | 1206мс | 13мс | 1542мс |
Структура | 0мс | 19мс | 188мс | 2мс | 1629мс | 18мс | 2223мс |
Запрос | 0мс | 24мс | 313мс | 3мс | 2071мс | 21мс | 2250мс |
Настройки Компоновки Данных | 0мс | 53мс | 732мс | 2мс | 2094мс | 20мс | 2649мс |
Настройки Компоновки Данных В2 | 0мс | 53мс | 523мс | 2мс | 2367мс | 22мс | 2538мс |
ЗначениеВСтроку | 0мс | 42мс | 474мс | 2мс | 2264мс | 23мс | 2810мс |
XML | 1мс | 315мс | 3602мс | 20мс | 23069мс | 228мс | 23086мс |
Выводы:
Судя по замерам, метод с JSON хорош как при большом числе элементов в соответствии, так и при преобразовании в цикле. Нужно учесть недостатки, что ключ должен быть строкой, в которой только разрешенные символы. Соответственно если вы уверены, что ограничения нет, то почему бы и да?
На что еще хочется обратить внимание?
Циклы работают довольно-таки долго, но СериализаторXDTO.ЗаписатьXML и СериализаторXDTO.ПрочитатьXML работает крайне медленно, я бы сказал, отвратительно.
Обратите внимание, что при включенном и выключенном debug картина меняется и в местах где используется цикл с небольшим количеством элементов в соответствии выигрывает метод через структуру в цикле.
Так же есть важный нюанс отмеченный в комментариях, чем больше символов в значениях у соответствия, тем медленнее начинает работать способ с JSON (дополнительные замеры в комментариях).
На этом статью заканчиваю. Надеюсь, она была вам полезна.
П.С. Данная статья появилась благодаря читателям моего канала, она набрала оговоренное количество эмоций.