Как вы думаете, можно ли оптимизировать данный код? Как? Что будет результатом этого кода?
Для а = -ТаблицаЗначений.Количество() + 1 по 0 Цикл
Стр = ТаблицаЗначений[-а];
Если Стр.Количество = 0 Тогда
ТаблицаЗначений.Удалить(Стр);
КонецЕсли;
КонецЦикла;
(1) сделать запрос по данной таблице значений, поставить условие количество <> 0. Полученный результат выгрузить в другую таблицу значений. Если есть шанс, что и дальше в коде будете работать полученной таблицей значения, то в запросе используйте ещё и менеджер временных таблиц. Думаю больше некуда оптимизировать
(9) А зачем в СУБД? Давайте сразу превратим ТЗ в массив структур, пройдемся по каждой структуре, поудаляем элементы массива, в структуре которых нужные ключи = 0, потом обратно из массива структур сделаем ТЗ...
Можно еще в XML сериализовать, перевести в DOM-модель, и с помощью выражений XPath поудалять нулевые элементы, вернуть обратно в XML, и десериализовать обратно в ТЗ...
(26) включите замер производительности, и пройдитесь в одном коде по циклу к таблице несколько раз, а потом тоже самое но используя уже созданную временную таблицу и проверьте разницу
(27)Зачем проходить несколько раз?
В зависимости от задачи можно предложить разные варианты решения.
Если цель - из таблицы в 100000 строк получить другую таблицу, в которой только часть строк, то в общем случае можно в таблицу добавить колонку булевую, заполнить ее значением Истина для нужных строк и скопировать исходную таблицу с отбором по этой колонке.
В частных случаях, когда условие на равно, даже колонки добавлять не надо.
Если у вас есть реальные данные для теста, можете попробовать и сделать замер, у меня их нет.
Если СтрокаТЧ.Количество = 0 Тогда
ТаблицаЗначений.Удалить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
Самый оптимальный вариант.
Передавать как параметр в запрос мега глупая идея, потому что мало того такая операция считается ресурсоемкой, так помимо сервера 1с еще задействуется сервер sql, который возможно является другой машиной в сети, до которой по сети нужно таблицу передать. В свою очередь сервер sql сделает тоже самое - пробежится по всей таблице и удалит все строи из нее, и потом вернет результат, опять же возможно по сети.
НайтиСтроки - Сделает приблизительно тоже самое - пробежится по таблице и сравнит значение в колонке и запишет в массив строк, которые ты опять же должен удалить. Можно поэксперементировать на больших таблицах что быстрее - обойти циклом с конца и удалить или сначала найти все строки и после поштучно их удалить. Думаю первый вариант лучше.
ТаблицаЗначений.Индексы.Добавить("Количество");
МассивСтрок = ТаблицаЗначений.НайтиСтроки(Новый Структура("Количество",0));
Для Каждого Стр из массивСтрок Цикл
ТаблицаЗначений.Удалить(Стр)
КонецЦикла;
(4) вам что хочется в итоге получить?
туже самую таблицу, только без Количество = 0?
если посмотреть внимательно на ваш цикл, то после первого же удаления строки, индексы в таблице сменятся и уже второе удаление удалить не ту строку, что надо
(12)Потому что таблицу нужно передать в сторону сервера SQL, дождаться пока он из этой таблицы сделает временную таблицу, выделит ресурсы под индексы, обработает таблицу запросом с условием и вернет результат обратно.
Это все занимает время.
Существующая коллекция в виде ТЗ уже находится в ОЗУ сервера 1С и имеет собственные методы для фильтрации. Если существующих методов фильтрации ТЗ не хватает, то с помощью цикла реализуется нужный.
У нас в тестовом задании для программиста есть задача по удалению строк из таблицы по условию.
В основном делают:
1. Запросом - таблицу в запрос, там в отбор - выгрузка.
2. Обратном перебором.
3. Сбором ссылок удаляемых строк в массив .удаление строк.
Коллеги совсем забыли про СКД. Создаем схему СКД на основе набора-объект. В качестве внешнего набора подставляем нашу ТЗ. Создаем нужный отбор. Выгружаем результат СКД в коллекцию...
(7) Это вариант для сложной фильтрации, например, с обращением к полям через точку для установки условия. А так, если рассматривать примитивное условие на "Количество = 0", то конечно, вариант с запросом на больших объемах данных проиграет.
И уж, если мы говорим о конкретной задаче и принимаем в качестве условия, что какие-то строки не нужны для дальнейшей работы, то, в первую очередь, нужно посмотреть на реализацию алгоритма их получения, и, если это возможно, в принципе не добавлять их в ТЗ.
(21)В задаче предельно ясно описан код. Из кода, думаю, большинству ясно, что никаких "мудреных" фильтраций не нужно.
Зачем придумывать условия задачи и потом успешно решать задачу в этих придуманных условиях?
(22) Отвечая на вопросы на форуме, я обычно стараюсь, дать ответ, который может выходить за рамки вопроса. Так делаю, потому что допускаю, что другие специалисты, преимущественно начинающие, могут искать подобный кейс, но со своими нюансами.
Мне нравится обсуждение этого вопроса, здесь можно понять какие есть варианты в принципе (не исчерпывающие конечно), какие нужно использовать в конкретном кейсе, какие в более сложном.
Хороший код в (0), минимальное количество операций и дополнительных переменных. Все остальные варианты будут избыточными и смысл в них только для красоты:
Для Каждого Ст ИЗ Таблица.НайтиСтроки( Новый Структура("Количество", 0) ) Цикл
Таблица.Удалить( Ст );
КонецЦикла;
Да, строк меньше, код лаконичнее, но, думаю, то же самое время займет и ресурсы.
Немного тестов:
Удаление перебором: 203
Удаление через НайтиСтроки: 109
Удаление запросом: 203
Удаление обратным условием: 515 Некорректный тест – в запрос должна быть загружена вся ТЗ целиком.
Думаю, что если не выделять отдельный массив (в цикле итерируемый список итак рассчитывается однократно) и записать все в одну строку, как Вы сделали для других методов, можно и ускорить чуток.
(39) в общем в минимализмах вариант не самый быстрый оказался, а самый банальный вариант оказался быстрее всего )))
Но вообще думаю, что стоит замерить каждый метод на чувствительность к количеству удаляемых строк. Сейчас в тесте 10% строк, которые подлежат удалению. Что произойдет, если количество строк вырастет до 90%?
Есть предположение, что структура темп таблицы кешируется после первого запроса. Во всяком случае, последующие тесты с запросом выдают относительное время лучше, чем первый раз.
(45) Это странно. У меня клиент-сервер, без отладки, чистая конфигурация. После перезапуска при 50%:
Удаление перебором: 391
Удаление через НайтиСтроки: 375
Удаление запросом: 2 703
Удаление обратным условием: 375
(48) да, действительно если просто "*" поставить в ВТ, то все приобретает иной оборот (думал, что у Вас там * и так стоит, не предполагал даже, что Вы так с полями извращаться будете)))))