Нужно ли проверять количество элементов коллекции перед циклом Для Каждого?

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

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

Техническое поведение платформы в цикле Для Каждого

Разберем, как ведет себя платформа 1С при выполнении цикла Для Каждого. Когда интерпретатор доходит до строки начала цикла, он инициализирует итератор для указанной коллекции. Если коллекция (например, Массив или ТаблицаЗначений) пуста, итератор сразу определяет, что элементов для обхода нет. В этом случае управление передается на строку, следующую за КонецЦикла. Никаких ошибок типа "обращение по пустому индексу" или исключений в штатных объектах 1С не возникает.

Таким образом, с технической точки зрения код ниже абсолютно безопасен, даже если СписокТоваров не содержит ни одной строки:


Для Каждого СтрокаТовара Из СписокТоваров Цикл
    // Этот блок просто не будет выполнен
    ОбработатьСтроку(СтрокаТовара);
КонецЦикла;

Анализ производительности и замеры

Существует мнение, что проверка Количество() > 0 помогает сэкономить время на создании объекта-итератора. Давайте проанализируем результаты замеров, которые провели участники обсуждения. Рассмотрим два варианта кода и их скорость выполнения при большом количестве итераций (например, 100 000 раз).

Вариант 1: Прямой обход пустой таблицы


Для Счетчик = 1 По КоличествоПроходов Цикл
    Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
        // Пусто
    КонецЦикла;
КонецЦикла;

Вариант 2: Обход с предварительной проверкой количества


Для Счетчик = 1 По КоличествоПроходов Цикл
    Если ТаблицаЗначений.Количество() > 0 Тогда
        Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
            // Пусто
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

По результатам тестов выяснилось, что разница во времени выполнения между этими вариантами ничтожна. В некоторых случаях вариант с лишним Если оказывался даже чуть медленнее из-за необходимости выполнения дополнительной операции вызова метода Количество(). Современная платформа оптимизирована таким образом, что инициализация пустого цикла происходит мгновенно.

Когда проверка Количество() > 0 действительно необходима

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

  1. Наличие ветки Иначе: Если бизнес-логика требует совершить действие в случае отсутствия данных (например, вывести сообщение "Список пуст" или заполнить таблицу значениями по умолчанию), то использование Если необходимо.
    
    Если Товары.Количество() > 0 Тогда
        Для Каждого Стр Из Товары Цикл
            // Обработка
        КонецЦикла;
    Иначе
        Сообщить("Нет данных для обработки!");
    КонецЕсли;
    
  2. Группировка ресурсоемких операций: Представим ситуацию, когда перед циклом нужно выполнить тяжелую инициализацию (создать COM-объект, прочитать файл или подготовить структуру в памяти), которая нужна только при наличии элементов в коллекции. В этом случае проверка экономит ресурсы сервера.
  3. Сложные условия в ИначеЕсли: Как было замечено в обсуждении, проверка может быть частью цепочки условий, где обход коллекции — это лишь один из вариантов развития алгоритма.

Стандарты разработки и "Чистый код"

Согласно системе стандартов и методических рекомендаций по разработке на платформе "1С:Предприятие", избыточный код считается негативным фактором. Лишние блоки Если увеличивают уровень вложенности кода, что делает его менее читаемым ("спагетти-код").

Проанализируем рекомендации "чистого кода": если алгоритм позволяет избежать вложенности, это следует сделать. Код, в котором отсутствует лишняя проверка перед циклом, выглядит более лаконично и профессионально, так как показывает понимание разработчиком принципов работы платформы.

Особенности работы с внешними источниками

Стоит упомянуть исключительные случаи. При работе с COM-соединениями или внешними библиотеками (например, обход коллекции элементов в Excel), обращение к итератору может вести себя непредсказуемо. В таких специфических задачах проверка количества элементов или проверка на Неопределено может служить защитным механизмом. Однако для стандартных объектов 1С (Массив, ТаблицаЗначений, СписокЗначений, Структура) это не требуется.

Различие между Коллекциями и Выборками

Важно не путать коллекции, обходящиеся через Для каждого, и выборки из базы данных (РезультатЗапроса.Выбрать()). Хотя для выборки тоже можно проверить Количество(), стандартный цикл Пока Выборка.Следующий() Цикл также является абсолютно безопасным для пустых наборов данных. Использование проверки перед Следующий() обычно продиктовано желанием пропустить какую-то сложную логику подготовки данных, которая идет до цикла.

Выводы

Подводя итог нашему анализу, можно сформулировать следующие правила:

← На главную