Как лучше задавать массив в 1С: через конструктор или методом Добавить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Варианты инициализации массива

Рассмотрим две основные ситуации, которые чаще всего встречаются в коде. Представим, что нам нужно создать массив из двух элементов и заполнить его ссылками на предопределенные данные.

Вариант 1: Предварительное определение размера

В этом случае мы сразу сообщаем платформе, сколько элементов будет в массиве, и обращаемся к ним по индексу:


Массив = Новый Массив(2);
Массив[0] = ПланыВидовХарактеристик.Субконто.Номенклатура;
Массив[1] = ПланыВидовХарактеристик.Субконто.Склад;

Вариант 2: Динамическое добавление

Здесь мы создаем пустой объект и последовательно увеличиваем его размер с помощью встроенного метода:


Массив = Новый Массив;
Массив.Добавить(ПланыВидовХарактеристик.Субконто.Номенклатура);
Массив.Добавить(ПланыВидовХарактеристик.Субконто.Склад);

Проанализируем производительность на больших объемах

Чтобы выяснить, есть ли реальная разница в скорости работы, обратимся к результатам нагрузочного тестирования. Если на двух элементах разница незаметна, то на 100 000 итераций она должна проявиться. Разберем код теста:


// Тест динамического добавления
МассивДанных = Новый Массив();
Для Инд = 1 По 100000 Цикл
    МассивДанных.Добавить(ПланыВидовХарактеристик.ВидыСубконто.Номенклатура);
КонецЦикла;

// Тест обращения по индексу
МассивДанных = Новый Массив(100000);
Для Инд = 1 По 100000 Цикл
    МассивДанных[Инд-1] = ПланыВидовХарактеристик.ВидыСубконто.Номенклатура;
КонецЦикла;

Практические замеры показывают, что разница во времени выполнения этих двух циклов находится в пределах погрешности. Почему так происходит? В отличие от языков программирования низкого уровня, в 1С механика выделения памяти под массив работает по принципу «блочного резервирования». Платформа выделяет память не под каждый новый элемент, а сразу под группу. Это минимизирует количество тяжелых операций перераспределения памяти (realloc) при использовании метода Добавить().

Технические нюансы: ловушка «двойной записи»

Важно понимать внутреннюю логику работы конструктора Новый Массив(N). Когда мы пишем Новый Массив(100), платформа выполняет следующие действия:

  1. Выделяет память под 100 ячеек.
  2. Автоматически заполняет каждую ячейку значением Неопределено.

Затем, когда мы начинаем заполнять массив данными через Массив[Индекс] = Значение, мы фактически перезаписываем уже существующие данные. Таким образом, вариант с предварительным указанием размера заставляет платформу делать лишнюю работу по инициализации ячеек значениями по умолчанию. В случае же с Добавить() запись значения в память происходит ровно один раз.

Стандарты разработки и читаемость кода

С точки зрения стандартов разработки «1С», вариант №2 (через Добавить) является предпочтительным по нескольким причинам:

Когда действительно нужно задавать размер в конструкторе?

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


// Создаем матрицу 10 на 10
МногомерныйМассив = Новый Массив(10, 10);

Попытка реализовать это через вложенные циклы и методы Добавить() сделает код громоздким и менее понятным для коллег.

Оптимизация: ФиксированныйМассив и СтрРазделить

Если ваша цель — максимальная оптимизация, рассмотрим еще два полезных инструмента, упомянутых экспертами:

1. ФиксированныйМассив
Если после создания массива вы планируете только читать из него данные, рекомендуется преобразовать его в ФиксированныйМассив. Это особенно полезно при передаче данных между клиентом и сервером, так как такие объекты защищены от записи и могут обрабатываться платформой эффективнее.


Массив = Новый Массив;
Массив.Добавить(ПланыВидовХарактеристик.Субконто.Номенклатура);
ФиксМассив = Новый ФиксированныйМассив(Массив);

2. Метод СтрРазделить
Если вам нужно заполнить массив строковыми значениями (например, из списка, разделенного запятыми), использование встроенной функции СтрРазделить будет работать в несколько раз быстрее любого цикла, так как эта функция реализована на уровне ядра платформы.


СписокИмен = "Номенклатура,Склад,Организация";
МассивИмен = СтрРазделить(СписокИмен, ",");

Подведем итог

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

← На главную