По теме из базы знаний
Найденные решения
(1) Добрый день. Удалять надо так:
Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;
где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;
где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(3) Можно и не обходить. Автор-то не приводит свой код и не ясно что ему нужно. Лишь что-то ищет функцией Найти и удаляет. В этом случае обход может и не понадобится.
Вот куча способов удаление.
Вот куча способов удаление.
// 1. Удаление строк согласно условию
НулевыеСтроки = ТаблицаПослеПодмен.НайтиСтроки(Новый Структура("Сумма",0));
Для каждого СтрокаТаблицы Из НулевыеСтроки Цикл
ТаблицаПослеПодмен.Удалить(СтрокаТаблицы)
КонецЦикла;
// Нужно оставить строки только соответствующие условию,а остальные удалить то:
ПараметрыОтбора = Новый Структура("Цена",15000);
ТЗНов = ТЗ.Скопировать(ПараметрыОтбора);
// в результате в ТЗнов будут только строки из ТЗ, в которых значение поля Цена = 15000
// 2. Удаление определенной строки, например УдаляемаяСтрока = 5;
ТаблицаЗначений.Удалить(УдаляемаяСтрока);
// 3. Удаление первой строки
ТаблицаЗначений.Удалить(0);
// 4. Удаление определенной колонки, например УдаляемаяКолонка = 3;
ТаблицаЗначений.Колонки.Удалить(УдаляемаяКолонка);
// 5. Удалить первую колонку
ТаблицаЗначений.Колонки.Удалить(0);
// 6. Удаление строк перебором, проверяя условие
СтаршийИндексКолонок = ТаблицаЗначений.Колонки.Количество() - 1;
Индекс = ТаблицаЗначений.Количество() - 1;
Пока Индекс > = 0 Цикл
Для Сч = 0 По СтаршийИндексКолонок Цикл
Если ТипЗнч(ТаблицаЗначений[Индекс][Сч]) = Тип("Число") Тогда
ТаблицаЗначений.Удалить(Индекс);
Прервать;
КонецЕсли;
КонецЦикла;
Индекс = Индекс - 1;
КонецЦикла;
Показать
(1) Добрый день. Удалять надо так:
Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;
где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
Сч = 0;
Пока (Сч < ТаблицаДанных.Количество ()) Цикл
Строка = ТаблицаДанных.ПолучитьСтроку (Сч);
Если (УдаляемСтроку (Строка)) Тогда
ТаблицаДанных.Удалить(Сч);
Иначе
Сч = Сч + 1;
КонецЕсли;
КонецЦикла;
где Функция УдаляемСтроку () - анализ строки на удаление. Работает правильно и быстро.
(10) Ну, тогда можете так:
И теперь удаляйте строки в ТаблицаДанных из списка строк Строки
Хотя, это уже изврат если просто нужно удалить строки по какому - то простому условия. Этот алгоритм имеет смысл только если удаление строки зависит от данных в других строках. Тогда да.
ТаблицаДанных.Колонки.Добавить ("Удалить");
Для Каждого ТекСтрока Из ТаблицаДанных Цикл
ТекСтрока.Удалить = УдаляемСтроку (Строка);
КонецЦикла;
ОтборСтрок = Новый Структура ("Удалить", Истина);
Строки = ТаблицаДанных.НайтиСтроки (ОтборСтрок );
ТаблицаДанных.Колонки.Удалить("Удалить");
И теперь удаляйте строки в ТаблицаДанных из списка строк Строки
Хотя, это уже изврат если просто нужно удалить строки по какому - то простому условия. Этот алгоритм имеет смысл только если удаление строки зависит от данных в других строках. Тогда да.
(19)
:-)) Я понимаю, что причина в номерах строки, что сбивается. И в решении было видно, что работа идет с этим. А в вашем решении как будто 2 раза одно и тоже по циклу проходит. Код не только должен работать, но и быть понятным, мне просто другой вариант был чисто визуально понятнее. Может он по другим параметрам уступает, но тут это не так важно, этот объект пользователи используют самое частое раз в день. А по факту за прошлый год раз 10. Строк там мало, 5-6. Поэтому не так важно, сколько он будет отрабатывать.
А чем не понравился мой вариант (4) с хранением строк которые потом нужно удалить в отдельном массиве? Тем более что если речь идет о таблицах которые динамически отражаются на экране то добавление лишней колонки отнимет лишнее время :)
:-)) Я понимаю, что причина в номерах строки, что сбивается. И в решении было видно, что работа идет с этим. А в вашем решении как будто 2 раза одно и тоже по циклу проходит. Код не только должен работать, но и быть понятным, мне просто другой вариант был чисто визуально понятнее. Может он по другим параметрам уступает, но тут это не так важно, этот объект пользователи используют самое частое раз в день. А по факту за прошлый год раз 10. Строк там мало, 5-6. Поэтому не так важно, сколько он будет отрабатывать.
(19) Ну, это уже кому как нравиться. Приносить в жертву понятность и легкость восприятия программного кода в угоду лишней миллисекунде выполнения кода - я думаю, что не стоит. Если бы тут был объем данных, скажем, строк миллиард, то да. Я бы тогда написал уже код или с индексами, или методы статистического анализа применил. Или метод золотого сечения и пр. А тут задача локальная. Мне кажется, что не стоит.
(6) У вас похоже самый медленный алгоритм удаление из всех представленных. В каждой итерации вычисляется количество строк всей таблицы ТаблицаДанных.Количество () и доп.условия. Чтобы этого не было нужно перебирать с конца, как говорили остальные комментаторы.
Самый быстрый и легкий путь:
Ну если прямо хочется перебирать с начала по каким-то неведомым причинам, то хотя бы нужно переписать ваш код:
Самый быстрый и легкий путь:
Индекс = ТаблицаЗначений.Количество() - 1;
Пока Индекс >= 0 Цикл
Если УсловиеДляУдаленияСтроки(ТаблицаЗначений[Индекс]) Тогда
ТаблицаЗначений.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
ПоказатьНу если прямо хочется перебирать с начала по каким-то неведомым причинам, то хотя бы нужно переписать ваш код:
Количество = ТаблицаДанных.Количество();
Сч = 0;
Пока (Сч < Количество) Цикл
Если (УдаляемСтроку(ТаблицаДанных[Сч])) Тогда
ТаблицаДанных.Удалить(Сч);
Количество = ТаблицаДанных.Количество();
Продолжить;
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
Показать
(16) Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица. Так что Вы тут не правы. Это аналог TList -
TList *List = new TList;
for (int i = 0; i < 10; i++)
{
List-Add((void *)(new float[10]));
}
и здесь при обращении int Num = List->Count - также не вычисляется кол-во элементов в списке List, - он просто храниться в свойстве потомка класса.
TList *List = new TList;
for (int i = 0; i < 10; i++)
{
List-Add((void *)(new float[10]));
}
и здесь при обращении int Num = List->Count - также не вычисляется кол-во элементов в списке List, - он просто храниться в свойстве потомка класса.
(18) для небольших данных разница будет не существенна. На больших уже заметна.
Вот тест:
Для КоличествоСтрокТЗ = 1 000 000
Тест1: "Время выполнения: 7 128"
Тест2: "Время выполнения: 6 781"
Вот тест:
&НаКлиенте
Процедура Тест1(Команда)
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сч = 0;
Пока (Сч < ТЗРезультат.Количество()) Цикл
Сч = Сч + 1;
КонецЦикла;
ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
&НаКлиенте
Процедура Тест2(Команда)
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сч = 0;
Пока (Сч < КоличествоСтрокТЗ) Цикл
Сч = Сч + 1;
КонецЦикла;
ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
ПоказатьДля КоличествоСтрокТЗ = 1 000 000
Тест1: "Время выполнения: 7 128"
Тест2: "Время выполнения: 6 781"
(24) Ну, во первых тут у Вас время в миллисекундах, и 200 миллисекунд разница. Для чистоты эксперимента надо прогнать алгоритм раз 100 и усреднить. Т.к. при запуске алгоритмов включается такие процессы, как использование кеша процессора/запуск других служб винды и пр. Тут судить нельзя по одному тесту. А во вторых:
Ну, это уже кому как нравиться. Приносить в жертву понятность и легкость восприятия программного кода в угоду лишней миллисекунде выполнения кода - я думаю, что не стоит. Если бы тут был объем данных, скажем, строк миллиард, то да. Я бы тогда написал уже код или с индексами, или методы статистического анализа применил. Или метод золотого сечения и пр. А тут задача локальная. Мне кажется, что не стоит.
Ну, это уже кому как нравиться. Приносить в жертву понятность и легкость восприятия программного кода в угоду лишней миллисекунде выполнения кода - я думаю, что не стоит. Если бы тут был объем данных, скажем, строк миллиард, то да. Я бы тогда написал уже код или с индексами, или методы статистического анализа применил. Или метод золотого сечения и пр. А тут задача локальная. Мне кажется, что не стоит.
(18) А вот когда в ТЗ меняются строки, то становится совсем интересно:
Для КоличествоСтрокТЗ = 100 000
Тест1: Время выполнения: 26 286
Тест2: Время выполнения: 20 127
Более 6 секунд на 100 000 строках. Половина из которых удаляется.
Вот это уже затратно.
&НаКлиенте
Процедура Тест1(Команда)
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сч = 0;
Пока (Сч < ТЗРезультат.Количество()) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Тест1: Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
&НаКлиенте
Процедура Тест2(Команда)
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сч = 0;
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Тест2: Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
ПоказатьДля КоличествоСтрокТЗ = 100 000
Тест1: Время выполнения: 26 286
Тест2: Время выполнения: 20 127
Более 6 секунд на 100 000 строках. Половина из которых удаляется.
Вот это уже затратно.
(25) Хм. Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк. И вот в этом алгоритме -
будет увеличение времени на пересчет.
А при удалении строк в алгоритме
пересчет количества строк не будет - у Вас в переменной хранится (и процессор деление на два заменить на битовый сдвиг) - вы же не знаете сколько строк будет удалено. А тут у Вас известно - ровно половина. Этот алгоритм попахивает нечистотой эксперимента.
Пока (Сч < ТЗРезультат.Количество()) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
будет увеличение времени на пересчет.
А при удалении строк в алгоритме
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
пересчет количества строк не будет - у Вас в переменной хранится (и процессор деление на два заменить на битовый сдвиг) - вы же не знаете сколько строк будет удалено. А тут у Вас известно - ровно половина. Этот алгоритм попахивает нечистотой эксперимента.
(28)
ок. смотрим (18):
Комментировать и правда нечего. Все и так понятно.
Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк.
ок. смотрим (18):
Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица
Комментировать и правда нечего. Все и так понятно.
(29) Если Вы удаляете из таблицы строку, то из переменной ответственной за хранение кол-ва строк в таблице вычитается 1-ца. Это не относится к тому, что каждый раз при обращении к функции Количество() таблицы значений программа будет каждый раз пробегаться по строкам таблицы и подсчитывать их количество - так никто не делает при разработке компилятора транслятора - делают через хранение кол-ва строк в отдельной переменной - свойстве класса. Это же элементарно :-)
(30) действительно не понимаете о чем речь, или специально в другую сторону уводите?
Удаление строк одинаково в обоих случаях. Тест1 и Тест2.
Если не удалять строки, то разница во времени выполнения не принципиальная. Логично, вычисление ТЗ.Количество() просто кешируется.
Если происходит удаление, то Количество() каждый раз выполняется. И разница во времени становится уже очень заметна.
Так что не надо говорить, что с условием ТЗ.Количество() не будет разницы. Вот о чем речь.
Удаление строк одинаково в обоих случаях. Тест1 и Тест2.
Если не удалять строки, то разница во времени выполнения не принципиальная. Логично, вычисление ТЗ.Количество() просто кешируется.
Если происходит удаление, то Количество() каждый раз выполняется. И разница во времени становится уже очень заметна.
Так что не надо говорить, что с условием ТЗ.Количество() не будет разницы. Вот о чем речь.
(29) А у Вас метод такой - Вы задаете программе сколько надо удалить строк, и начинаете это количество строк удалять. Вопрос - откуда Вы знаете сколько строк надо удалить?
как у Вас:
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
тут Вы откуда то еще до анализа таблицы уже знаете, что надо удалить половину строк таблицы.
как у Вас:
Пока (Сч < КоличествоСтрокТЗ/2) Цикл
Если Сч%2 = 0 Тогда
ТЗРезультат.Удалить(Сч);
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
тут Вы откуда то еще до анализа таблицы уже знаете, что надо удалить половину строк таблицы.
(33) Ну а причем тут четные элементы выборки? - прочитайте постановку задачи у автора - ему надо удалить не четные элемент выборки, а анализировать строку на необходимость удаления. Зачем Вы делаете искусственные предположения, когда задача ясна из постановки?
(34) мы не обсуждаем сейчас алгоритм автора топика. Мы обсуждаем утверждение, что:
и второе противоречащее утверждение:
Я привел абстрактный Тест проверки этих утверждений. Оба теста выполняют одинаковую работу. У обоих одинаковая итерация.
Вообще - то количество строк вычисляется компилятором не при каждом обращении к функции КоличестроСтрок(), а просто возвращается из предвычисленного параметра. Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица.
и второе противоречащее утверждение:
Я даже не знаю как это комментировать. Неужели не понятно, что при удалении строки будет пересчет количества строк.
Я привел абстрактный Тест проверки этих утверждений. Оба теста выполняют одинаковую работу. У обоих одинаковая итерация.
(36) ок. Вот еще тест:
Объясню алгоритм. Не важно сколько элементов в ТЗ. Всегда будут выполняться только проход и удаление первых 1000 элементов.
И вот итог:
Кол-во элементов в ТЗ | Время мсек
10 000 | 99
100 000 | 997
1 000 000 | 15 532
Показательно. Каждый раз именно рассчитывается количество элементов.
&НаКлиенте
Процедура Тест3(Команда)
ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сч = 0;
Пока (Сч < ТЗРезультат.Количество()) Цикл
Если Сч < 1000 Тогда
ТЗРезультат.Удалить(Сч);
Иначе
Прервать;
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
Сообщить("Тест3: Время выполнения: "+(ВремяОкончания - ВремяНачала));
КонецПроцедуры
ПоказатьОбъясню алгоритм. Не важно сколько элементов в ТЗ. Всегда будут выполняться только проход и удаление первых 1000 элементов.
И вот итог:
Кол-во элементов в ТЗ | Время мсек
10 000 | 99
100 000 | 997
1 000 000 | 15 532
Показательно. Каждый раз именно рассчитывается количество элементов.
(38) Нет, неправильно. При удалении строки производится перераспределение памяти. Если таблица большая, то и времени на перераспределение памяти больше. Это не относится к расчету кол-ва строк.
Аналог TList в c++ builder. Кстати, в предыдущих Ваших алгоритмах - тоже такая ситуация может быть. Т.к. все зависит от заполненности "кучи" памяти. И для чистоты эксперимента надо прогнать алгоритм раз 50 и потом усреднить.
Аналог TList в c++ builder. Кстати, в предыдущих Ваших алгоритмах - тоже такая ситуация может быть. Т.к. все зависит от заполненности "кучи" памяти. И для чистоты эксперимента надо прогнать алгоритм раз 50 и потом усреднить.
(40) как это соотносится с:
Предыдущие тесты (Тест1 и Тест2) оба удаляют строку. Временные затраты на это одинаковые.
Не надо притягивать алгоритмы с++ builder на работу 1С кода.
Т.к. КоличествоСтрок() - это просто функция которая возвращает свойство таблицы КоличествоСтрок. При удалении строки из этого свойства вычитается 1-ца, а при добавлении строки добавляется единица.
Предыдущие тесты (Тест1 и Тест2) оба удаляют строку. Временные затраты на это одинаковые.
Не надо притягивать алгоритмы с++ builder на работу 1С кода.
(41) Относится просто - когда Вы удаляете строку из таблицы с кол-вом строк в 1000 - это одно, а когда из таблицы с кол-вом строк в 1000000 - это другое. Накладные расходы на перераспределение памяти в таблицах с разным кол-вом строк - разное. А по поводу c+++ builder - это я Вам пример привел просто для понимания - т.к. ТаблицаЗначений в 1С - это STL - контейнер. А TList в c++ builder - это динамический список очень похожий на STL - контейнер.
(43) очередная попытка притянуть функциональность c++ builder к 1С.
В каком месте мы вызываем delete объекту? Согласно с++ объекты созданные в куче без явного удаления не уничтожаются.
Где мы выделяем память новому объекту?
Не стоит лезть во внутреннее строение платформы, не зная его механизмов.
В каком месте мы вызываем delete объекту? Согласно с++ объекты созданные в куче без явного удаления не уничтожаются.
Где мы выделяем память новому объекту?
Не стоит лезть во внутреннее строение платформы, не зная его механизмов.
(46) delete вызывается неявно. Иначе бы при удалении строк/таблицы была бы утечка памяти. Это, я думал, все знают и не стал это писать.
То что Вы пишите - "Согласно с++ объекты созданные в куче без явного удаления не ничтожаются." - т.е. Вы хотите сказать, что когда я:
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?
тогда сделайте миллиард Табл = Новый ТаблицаЗначений и также миллиард Табл = НеОпределено и посмотрите сколько памяти у Вас осталось. Уверяю - столько же.
"Где мы выделяем память новому объекту? " - когда делаете Новый (аналог new c++) - это и есть выделение памяти под новый объект.
То что Вы пишите - "Согласно с++ объекты созданные в куче без явного удаления не ничтожаются." - т.е. Вы хотите сказать, что когда я:
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?
тогда сделайте миллиард Табл = Новый ТаблицаЗначений и также миллиард Табл = НеОпределено и посмотрите сколько памяти у Вас осталось. Уверяю - столько же.
"Где мы выделяем память новому объекту? " - когда делаете Новый (аналог new c++) - это и есть выделение памяти под новый объект.
(48)
Если вот это дословно перевести на c++, то да. Будет явная утечка памяти.
Потому и говорю, не надо прямую ассоциацию приводить с с++
Вы хотите сказать, что когда я:
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?
Табл = Новый ТаблицаЗначений
и потом
Табл = НеОпределено
память выделенная под Табл не возвращается операционке?
Если вот это дословно перевести на c++, то да. Будет явная утечка памяти.
Потому и говорю, не надо прямую ассоциацию приводить с с++
(42) Перераспределение памяти при удалении строки, а не перераспределении в списке. Т.к. память высвобождается и отдается операционке для использования другими процессорами - иначе была бы утечка памяти (хотя, этого добра хватает в 1С :-) ). Или Вы думаете что это бесплатная операция? - и на нее не тратится тактов процессора?
(45) Зависят очень просто - чем больше сама таблица - тем больше она занимает страниц памяти. При удалении строк которые находятся в разных дампах(страницах) памяти процу приходится активно переключаться между дампами (страницами). Если таблица маленькая, и она убирается в одну страницу, то работа происходит в контексте одной страницы. Это если организована постраничная адресация. Если используется плоская модель памяти - то тут, возможно (надо посмотреть) и не будет увеличения времени удаления. + ко всему прочему надо учитывать объем кеша проца и какой объем данных закеширован.
(47) Еще раз - в (43) было заявлено, что удаление ОДНОЙ строки в таблице бОльшего размера займет больше времени.
И теперь пытаетесь подвести под это утверждение что? Что одна строка в большой таблице будет занимать несколько страниц памяти? И при каждом удалении строки будет осуществляться возврат памяти операционке? Признайтесь, что ошиблись и перестаньте нести бред.
Насчет возврата памяти операционке - ознакомьтесь со значением слова "куча", которое вы тут употребляли и как она работает.
И теперь пытаетесь подвести под это утверждение что? Что одна строка в большой таблице будет занимать несколько страниц памяти? И при каждом удалении строки будет осуществляться возврат памяти операционке? Признайтесь, что ошиблись и перестаньте нести бред.
Насчет возврата памяти операционке - ознакомьтесь со значением слова "куча", которое вы тут употребляли и как она работает.
(9)
УдаляемыеСтроки=новый массив;
Для каждого Строка из ТЗ Цикл
НайденнаяСтрока = Список.Найти(Строка.Колонка, "Колонка");
Если НайденнаяСтрока = Неопределено Тогда
УдаляемыеСтроки.Добавить(Строка);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемаяСтрока из УдаляемыеСтроки Цикл
ТЗ.Удалить(УдаляемаяСтрока);
КонецЦикла;
Показать
Самый простой вариант:
УдаляемыеСтроки=новый массив;
Для Каждого СтрокаТЗ из ТЗ Цикл
Если СтрокаТЗ.Сумма<0 Тогда
УдаляемыеСтроки.Добавить(СтрокаТЗ);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемаяСтрока из УдаляемыеСтроки Цикл
ТЗ.Удалить(УдаляемаяСтрока);
КонецЦикла;
Показать
(14) Вот самый быстрый и просто способ из всех:
Индекс = ТаблицаЗначений.Количество() - 1;
Пока Индекс >= 0 Цикл
Если УсловиеДляУдаленияСтроки(ТаблицаЗначений[Индекс]) Тогда
ТаблицаЗначений.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
Показать
(17) Этот способ только на первый взгляд самый быстрый. Во-первых, его можно записать короче: Во-вторых, даже в таком виде он выполняется примерно столько-же, сколько (7). Метод в (7) экономит на времени итерации переменной цикла, которая оказывается не нужна, когда элемент удален.
Но оба они (7) и (16) сильно проигрывают (примерно в два раза) методу с предварительным отбором списка удаляемых строк через НайтиСтроки() как в (5).
Для Индекс = - РабочаяТаблица.Количество() + 1 По 0 Цикл
Если РабочаяТаблица[- Индекс][0] = 0 Тогда // условие удаления
РабочаяТаблица.Удалить(- Индекс)
КонецЕсли
КонецЦикла
Но оба они (7) и (16) сильно проигрывают (примерно в два раза) методу с предварительным отбором списка удаляемых строк через НайтиСтроки() как в (5).
Пока ТаблицаДанных.НайтиСтроки(Новый структура("Сумма", 0)).Количество() > 0 Цикл
ТаблицаДанных.Удалить(ГруппыНоменклатуры.НайтиСтроки(Новый структура("Сумма", 0))[0]);
КонецЦикла;
Хоть и поздно, но сейчас тоже гуглил эту проблему, попробовал лучший ответ, не вышло, но нашел свой вариант
Когда строк для удаления мало оптимально такой код.
Мы не гоняем данные в памяти, а просто перебираем.
Как говорится под каждую задачу, свое решение!
В УПП умудрились папку впихнуть в документ.
Мы не гоняем данные в памяти, а просто перебираем.
Как говорится под каждую задачу, свое решение!
Для Каждого Строка Из ОбъектыОшибок Цикл
Если Строка.Ключ = "2" И ТипЗнч(Строка.Объект) = Тип("ДокументСсылка.УстановкаЦенНоменклатуры") Тогда
ТекущийОбъект = Строка.Объект.ПолучитьОбъект();
Если ТекущийОбъект <> Неопределено Тогда
НужноЗаписать = Ложь;
Товары = ТекущийОбъект.Товары;
КоличествоСтрок = Товары.Количество();
ТекущийИндекс = КоличествоСтрок - 1;
Пока ТекущийИндекс >= 0 Цикл
СтрокаТовары = Товары.Получить(ТекущийИндекс);
Если СтрокаТовары.Номенклатура.ЭтоГруппа Тогда
Товары.Удалить(СтрокаТовары);
НужноЗаписать = Истина;
КонецЕсли;
ТекущийИндекс = ТекущийИндекс - 1;
КонецЦикла;
Если НужноЗаписать Тогда
ТекущийОбъект.Записать();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ПоказатьВ УПП умудрились папку впихнуть в документ.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот