К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: структура или соответствие — что быстрее

Структура или соответствие в 1С: что быстрее при поиске и вставке, чем отличаются по скорости и памяти, как выбрать тип коллекции и замерить производительность кода.

Вопрос «структура или соответствие — что быстрее» возникает почти у каждого разработчика 1С, когда коллекция начинает использоваться в циклах с тысячами итераций. Короткий ответ: для поиска значения по произвольному ключу соответствие работает быстрее, потому что внутри использует хеш-таблицу, а структура оптимизирована под фиксированный набор именованных полей. Но разница проявляется не всегда — на малых объёмах данных оба варианта работают практически одинаково.

Структура в 1С — это коллекция пар «ключ-значение», где ключ всегда строка, соответствующая правилам именования переменных (без пробелов, не начинается с цифры). Соответствие — коллекция пар, где ключом может быть значение любого типа: строка, число, ссылка на справочник, дата. Именно это различие определяет и сценарии применения, и разницу в производительности.

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

Чем структура отличается от соответствия на уровне устройства

Структура создаётся конструктором Новый Структура("Имя, Возраст", "Иван", 30) и предназначена для хранения небольшого набора именованных значений. Доступ к элементу возможен двумя способами: через точку (Структура.Имя) и через квадратные скобки со строковым ключом (Структура["Имя"]). Ключи должны быть корректными идентификаторами — это ограничение платформы.

Соответствие создаётся конструктором Новый Соответствие и наполняется методом Вставить(Ключ, Значение). Ключом может быть ссылка на объект базы, число, дата — то, что структура принять не сможет. Доступ к значению выполняется только через квадратные скобки или метод Получить(Ключ).

Внутренне соответствие реализовано как хеш-таблица: поиск ключа выполняется за почти постоянное время независимо от количества элементов. Структура исторически ориентирована на небольшое число полей, и при большом количестве ключей поиск в ней может выполняться медленнее. На практике разница становится заметной при сотнях и тысячах ключей и частых обращениях в цикле.

В каких операциях соответствие выигрывает по скорости

Главный сценарий, где соответствие заметно быстрее, — массовый поиск значений по ключу. Типичный пример: в цикле по строкам таблицы значений нужно проверять, встречалась ли уже такая номенклатура, и накапливать итоги. Если для этого использовать соответствие, где ключ — ссылка на номенклатуру, каждая проверка выполняется за постоянное время.

Второе преимущество — соответствие позволяет использовать сами ссылки как ключи, без преобразования в строку. Если бы вы пытались решить ту же задачу структурой, пришлось бы формировать строковый ключ из GUID ссылки, что добавляет лишние операции преобразования и увеличивает риск коллизий при неаккуратной реализации.

Вставка новых элементов в соответствие также масштабируется хорошо: добавление тысяч ключей не приводит к деградации скорости. У структуры при большом числе ключей и вставка, и поиск могут работать медленнее, хотя для типовых задач с 5–20 полями это не имеет значения.

Количество ключейДо нескольких десятков

Разницы в скорости между структурой и соответствием практически нет, выбирайте по удобству кода

Количество ключейСотни и тысячи

Соответствие предпочтительнее, особенно если поиск выполняется в цикле

Тип ключаСсылка, число, дата

Только соответствие: структура принимает ключи-идентификаторы в виде строк

НазначениеПередача параметров в процедуру

Структура читаемее и является общепринятым стандартом в типовых конфигурациях

Когда структура — правильный выбор

Структура остаётся стандартом для передачи именованных параметров между процедурами и функциями. Код вида Параметры.Организация читается легче, чем Параметры["Организация"], и это общепринятый стиль в типовых конфигурациях и библиотеке стандартных подсистем. Экономия долей миллисекунды здесь не оправдывает потерю читаемости.

Структура удобна для описания фиксированного набора полей: настройки отчёта, параметры обработки, реквизиты создаваемого документа. Конструктор со списком имён сразу задаёт состав полей, что служит самодокументацией кода.

Дополнительный плюс — метод Свойство("Имя", Значение), который проверяет наличие ключа и возвращает значение одним вызовом. У соответствия аналогичная проверка делается через Получить(Ключ) с последующим сравнением с Неопределено, что чуть многословнее.

Важно понимать: для коллекций с малым числом элементов (до нескольких десятков) разница в производительности между структурой и соответствием настолько мала, что не должна влиять на выбор. Выбирайте по смыслу задачи и удобству сопровождения.

Как самостоятельно замерить скорость на своём коде

Универсальные цифры из интернета мало полезны: реальная разница зависит от версии платформы, числа элементов и характера обращений. Корректный замер делается на вашем конкретном сценарии с помощью функции ТекущаяУниверсальнаяДатаВМиллисекундах().

Принцип замера: выполнить операцию (например, миллион обращений по ключу) в цикле для структуры и для соответствия, засечь время до и после, сравнить результаты. Цикл должен быть достаточно длинным — одиночные операции выполняются быстрее точности замера.

bsl
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
Для Н = 1 По 1000000 Цикл
    Значение = ТестовоеСоответствие.Получить(КлючПоиска);
КонецЦикла;
Длительность = ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало;
Сообщить("Соответствие: " + Длительность + " мс");
Порядок замера производительности
  1. 1
    Сформируйте тестовые коллекции с реалистичным числом элементов — как в боевом сценарии, а не три тестовых ключа
  2. 2
    Замерьте время цикла обращений для соответствия через ТекущаяУниверсальнаяДатаВМиллисекундах
  3. 3
    Повторите тот же цикл для структуры с теми же данными
  4. 4
    Прогоните замер 3–5 раз и сравните средние значения, чтобы исключить случайные всплески
  5. 5
    Примите решение по результатам: если разница меньше 10–15%, выбирайте вариант с более читаемым кодом

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

Типичные ошибки при выборе коллекции

Самая частая ошибка — использование массива или таблицы значений для поиска по ключу с перебором всех элементов. Линейный поиск по массиву из тысячи элементов внутри цикла по тысяче строк даёт миллион сравнений, тогда как соответствие решило бы задачу за две тысячи обращений к хеш-таблице. Это и есть главный источник «тормозящих» обработок.

Вторая ошибка — упаковка большого количества разнородных данных в структуру только потому, что «так привычнее». Если коллекция растёт динамически и в ней сотни ключей, это не структура по смыслу, а соответствие, и стоит использовать подходящий тип.

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

Типичные ошибки
01
Поиск по массиву перебором вместо соответствия — квадратичная сложность и зависание обработки на больших данных
02
Хранение ссылок в структуре через строковые ключи из GUID — лишние преобразования и риск ошибок в формировании ключа
03
Замена структур на соответствия без замера — усложнение кода без реального выигрыша
04
Проверка наличия ключа в соответствии через обработку исключения вместо Получить() — исключения дорогие и замедляют код
05
Игнорирование того, что структура фиксированной структуры с ФиксированнаяСтруктура не позволяет добавлять ключи — ошибки в runtime

Ограничения и подводные камни обеих коллекций

У соответствия есть важная особенность: метод Получить() для отсутствующего ключа возвращает Неопределено. Если в коллекции осмысленно хранятся значения Неопределено, отличить «ключа нет» от «ключ есть, но значение Неопределено» таким способом нельзя — это источник трудноуловимых ошибок логики.

Ключи соответствия сравниваются по значению, но для ссылочных типов сравнение идёт по ссылке: две разные переменные, указывающие на один элемент справочника, дадут один ключ. Это удобно, но требует внимательности при работе с объектами, полученными разными способами.

Структура не поддерживает произвольные ключи: попытка обратиться Структура["Ключ с пробелом"] вызовет ошибку, если такой ключ не был объявлен, а объявить ключ с пробелом через конструктор невозможно. Также существует фиксированная структура — её состав полей менять нельзя, попытка добавить ключ приведёт к ошибке выполнения.

Обе коллекции передаются в процедуры по ссылке: изменения внутри вызванной процедуры отразятся на оригинале. Если нужна независимая копия, её придётся создавать явно, перебирая элементы.

Практические рекомендации по выбору

Общее правило формулируется просто: тип коллекции выбирается по семантике задачи, а не по абстрактной скорости. Соответствие — это словарь для поиска по ключу. Структура — это именованный набор полей, аналог записи или объекта-параметра.

Маршрут решения

Как выбрать тип коллекции

Нужно искать значения по ключу в цикле или накапливать данные по уникальным ключамИспользуйте соответствие — поиск по хешу быстрее и ключи любого типа
Нужно передать в процедуру набор именованных параметровИспользуйте структуру — это стандарт типовых конфигураций и читаемый код
Ключи — ссылки, числа или даты, а не строки-идентификаторыТолько соответствие, структура такие ключи не поддерживает
Коллекция небольшая (до пары десятков элементов) и читается один разВыбирайте по удобству кода — разницы в скорости не будет
Обработка тормозит на больших объёмахСначала замерьте узкое место, затем замените линейный поиск на соответствие

В типовых конфигурациях вы встретите оба подхода: параметры процедур передаются структурами, а кэши и индексы для быстрого поиска строятся на соответствиях. Следование этой же логике в собственных разработках делает код предсказуемым для коллег и упрощает сопровождение.

Наибольший выигрыш от соответствия получается не от замены структуры, а от замены линейного поиска. Если в цикле по таблице значений вы ищете строки методом Найти() по значению колонки, перенос данных в соответствие с ключом по этому значению обычно ускоряет обработку в разы — это первое место, куда стоит смотреть при оптимизации.
ПЗ
Практическое замечание

FAQ: частые вопросы о структуре и соответствии

Что быстрее: обращение Структура.Ключ или Соответствие[Ключ]?

На небольших коллекциях разница практически незаметна. При большом числе ключей и частых обращениях соответствие обычно выигрывает за счёт хеширования. Точный ответ для вашего случая даст только замер на реальных данных через ТекущаяУниверсальнаяДатаВМиллисекундах.

Можно ли использовать ссылку на справочник как ключ структуры?

Нет. Ключи структуры — только строки, являющиеся корректными идентификаторами. Для ключей-ссылок используйте соответствие: оно принимает значения любых типов, включая ссылки, числа и даты.

Как проверить наличие ключа в соответствии без ошибки?

Вызовите метод Получить(Ключ) — он вернёт Неопределено, если ключа нет. Учтите нюанс: если значение Неопределено хранится в коллекции осмысленно, отличить отсутствие ключа от пустого значения таким способом не получится.

Что потребляет больше памяти — структура или соответствие?

Хеш-таблица соответствия обычно требует дополнительной памяти под служебные данные, но на типовых объёмах это несущественно. Проблемы с памятью возникают от самого объёма хранимых значений, а не от типа коллекции.

Стоит ли массово переписывать код со структур на соответствия ради скорости?

Нет. Без замера узкого места такая замена не даёт выигрыша, но повышает риск ошибок. Оптимизируйте только те участки, где замер показал реальную проблему, чаще всего это линейный поиск в циклах.

Чем фиксированная структура отличается от обычной?

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

Итог

Что важно запомнить

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