Курилка ТаблицаЗначений

Тема в разделе "Курилка", создана пользователем Leisan, 5 мар 2013.

  1. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Ну раз пошла такая пьянка.... Есть в вашем алгоритме косяк. Причем с моей точки зрения весомый
    Зачем перебирать ВСЕ строки раз (вы же не тупой) уже все отсортировано...
    Код:
    //Вместо
    Стр = тЗнач.КоличествоСтрок();
    //я бы сделал так
    стр=0;
    тЗнач.НайтиЗначение("Перемещение",Стр,"Имя");
    
  2. Vlan
    Offline

    Vlan Гость Гость

    А полностью можно привести ваш алгоритм? Я начинаю с конца, чтобы безболезненно удалять "отработанные" строки. Что получится, если начинать с начала, мне не ведомо.
  3. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Просто вы крутите все ТЗ. Зачем? достаточно половину. Ну или прерывать внешний цикл при нахождении оприходования (поступления кончились). Ну а внутренний наоборот (нет поступлений)
  4. Vlan
    Offline

    Vlan Гость Гость

    Чтобы прервать внешний цикл, достаточно вставить пару строк. Внутренний и так прерывается при первом совпадении. Начинать с начала или с конца - вопрос религии, все равно половина строк будет пройдена до нужного места. На таблице значений какого-то заметного прироста в скорости работы мы не получим, а код я делал для примера, чтобы человеку было максимально понятен ход моих рассуждений.
    И это... Мы все еще говорим о косяке или аргументы закончились? ;-)
  5. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Вышеописанного считаю достаточным. Увеличения скорости при уменьшении цикла - готов спорить. Все зависит от размера массива
  6. Vlan
    Offline

    Vlan Гость Гость

    Ну на каком размере увеличение будет заметно на глаз?
  7. Vlan
    Offline

    Vlan Гость Гость

    Я не поленился и сделал такой тестовый код:

    Код:
    Перем тЗнач;
    //*******************************************
    Процедура ДобавитьВтаблицу(Имя,Цена)
    тЗнач.НоваяСтрока();
    тЗнач.Имя = Имя;
    тЗнач.Цена = Цена;
    КонецПроцедуры
    //*******************************************
    Процедура Сформировать()
    ОчиститьОкноСообщений();
    тЗнач = СоздатьОбъект("ТаблицаЗначений");//Заполнение исходными данныыми таблицы значений
    тЗнач.НоваяКолонка("Имя");
    тЗнач.НоваяКолонка("Цена");
    тЗнач.НоваяКолонка("Имя2");
    тЗнач.НоваяКолонка("Цена2");
    Для сч = 1 по 1000 Цикл
    ДобавитьВтаблицу("Оприходование товара",сч);
    ДобавитьВтаблицу("Перемещение товара",сч);
    КонецЦикла;
    //*******************************************
    // Непосредственно начало преобразований
    тЗнач.Сортировать("Имя,Цена"); //Отсортируем по виду и цене
    Стр = тЗнач.КоличествоСтрок();
    Имя = "";
    Цена = 0;
    Пока Стр > 0 Цикл
    тЗнач.ПолучитьСтрокуПоНомеру(Стр);
    Если тЗнач.Имя <> "Оприходование товара" Тогда //Нас интересует только Перемещение
    Имя = тЗнач.Имя;
    Цена = тЗнач.Цена;
    Ошибка = 1;
    сч = Стр - 1;
    Пока сч > 0 Цикл
    тЗнач.ПолучитьСтрокуПоНомеру(сч);
    Если ((тЗнач.Имя = "Оприходование товара")
    И   (тЗнач.Цена  = Цена)
    И (ПустоеЗначение(тЗнач.Имя2) = 1))
    Тогда
    Ошибка = 0;
    тЗнач.УстановитьЗначение(сч,"Имя2",Имя); //Устанавливаем данные в ту половину таблицы, где Оприходование
    тЗнач.УстановитьЗначение(сч,"Цена2",Цена);
    тЗнач.УдалитьСтроку(Стр);
    Прервать;
    КонецЕсли;
    сч = сч - 1;
    КонецЦикла;
    Если Ошибка = 1 Тогда
    Сообщить("Для Перемещения с ценой "+Строка(Цена) + " нет соответствия!");
    КонецЕсли;
    Иначе		  // Как только дошли до Приходования, остановка
    Прервать;  //  Эти строчки комментируем  для замера скорости выполнения
    КонецЕсли;       
    Стр = Стр - 1;
    КонецЦикла;
    тЗнач.ВыбратьСтроки(); //Выводим получившуюся таблицу для проверки
    Пока тЗнач.ПолучитьСтроку() = 1 Цикл
    Сообщить(Строка(тЗнач.Имя)+" "+Строка(тЗнач.Цена)+" "+Строка(тЗнач.Имя2)+" "+Строка(тЗнач.Цена2));
    КонецЦикла;
    КонецПроцедуры
    
    Удивительно, но 1000 лишних строк совсем не повлияли на общее время выполнения. Чисто гипотетически конечно документов может быть и больше, но это может быть интересно только в качестве спортивного интереса.
  8. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Да. Но ведь не оптимальный код входит в привычку. Для примера пост http://www.1c-pro.ru/topic49362.html Лишние телодвижения в цикле. Да еще при расчете, да не под терминалом.... Просто вышеописанная задача слишком проста чтобы "недочет" себя показал во всей красе
  9. Vlan
    Offline

    Vlan Гость Гость

    Я бы сказал по-другому: нет привычки оптимизировать код, как это делают профессионалы. Иногда это помогает разобраться в собственных обработках годичной давности и внести нужные изменения по мере поступления новых вводных. А в приведенном примере решение лежит где-то на поверхности. Не верится, что проверка 10-ти условий в справочнике может так повлиять.
  10. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Вы не о том говорите. Или просто не хотите признать явный недочет. Допускаю что возможно мы по разному пишем код. Например "и так сойдет" для меня сразу не приемлемо. Даже на такой задаче.
  11. rshakiro
    Offline

    rshakiro Профессионал в 1С Команда форума

    Регистрация:
    17 мар 2011
    Сообщения:
    2.236
    Симпатии:
    144
    Баллы:
    104
    полностью согласен... Всегда нужно задумываться о дальнейшем развитии(оптимизации) написанного кода, хотя бы потому, чтобы не возвращаться к такой проблеме вновь(завтра возможно не будет времени исправлять написанное, другие задачи, проекты), и нужно всегда быть "на шаг впереди" поставленной задачи - сегодня эта обработка обрабатывает 100 документов, а завтра возможно 10000...
  12. Vlan
    Offline

    Vlan Гость Гость

    Да оптимизируйте на здоровье. Разве я против? Моя задача - получить на выходе обработки нужный результат. Если я добьюсь результата быстро - мне бонус. Если я буду тратить лишнее время на оптимизацию - никто не похвалит, иногда даже наоборот. Вот такая правда жизни. Кто живет только программированием, может себе позволить уделять все свое рабочее время только коду. Мы же в гимназиях не обучены, преобразования Фурье и Гильберта с Шульбертом в глаза не видели, поэтому нам простительно плодить несовершенные программы (которые, однако, работают).
  13. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Да ради бога.... Пишите как заблогорассудится. Вам просто указали на недостатки вашего алгоритма. Не более того.
  14. Vlan
    Offline

    Vlan Гость Гость

    Спасибо. Жаль, что я так и не увидел идеального кода, чтобы поучиться у гуру. Знаю-знаю: "в ЛС и за деньги..." :)
  15. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    По стилю написания вы довольно веселый человек. Легкий сарказм неплохо смотрится в тексте. Что же касается кода в исправленном виде - его никто меня лично и не просил написать. Да и зачем? Главное же идея. А жмакать по клавишам и первоклассник может.
  16. WaRDeR
    Offline

    WaRDeR Модераторы Команда форума Модератор

    Регистрация:
    23 ноя 2006
    Сообщения:
    3.263
    Симпатии:
    14
    Баллы:
    29
    Если не лень, для работы с ТЗ рекомендую проделать следующую операцию:
    1. Создать ТЗ на 5-7 колонок.
    2. Заполнить ТЗ произвольными данными на 15000-25000 строк
    3. Выполнить удаление строк построчно, сначала по порядку, а потом в обратном порядке.....

    Разница будет видна невооруженным глазом. А на ТЗ до 1000 строк ее не заметишь. Вот на таких примерах и оттачиваются ньюансы
  17. Vlan
    Offline

    Vlan Гость Гость

    А можно пример удаления построчно по порядку?
  18. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Код:
    ТЗ.УдалитьСтроку();
    ТЗ.ВыбратьСтроки();
  19. Vlan
    Offline

    Vlan Гость Гость

    Пришлось сделать тестовую обработку:

    Код:
    Перем тЗнач;
    //*******************************************
    Процедура ДобавитьВтаблицу(Имя,Цена)
    тЗнач.НоваяСтрока();
    тЗнач.Имя = Имя;
    тЗнач.Цена = Цена;
    тЗнач.Имя2 = Имя;
    тЗнач.Цена2 = Цена;
    тЗнач.Имя3 = Имя;
    тЗнач.Цена3 = Цена;
    КонецПроцедуры
    //*******************************************
    Процедура Сформировать()
    ОчиститьОкноСообщений();
    тЗнач = СоздатьОбъект("ТаблицаЗначений");
    тЗнач2 = СоздатьОбъект("ТаблицаЗначений");
    тЗнач.НоваяКолонка("Имя");
    тЗнач.НоваяКолонка("Цена");
    тЗнач.НоваяКолонка("Имя2");
    тЗнач.НоваяКолонка("Цена2");
    тЗнач.НоваяКолонка("Имя3");
    тЗнач.НоваяКолонка("Цена3");
    Для сч = 1 по 15000 Цикл
    ДобавитьВтаблицу("Оприходование товара",сч);
    ДобавитьВтаблицу("Перемещение товара",сч);
    КонецЦикла;
    тЗнач2.Загрузить(тЗнач);
    Вр1 = ТекущееВремя();
    Стр = тЗнач.КоличествоСтрок();
    Пока Стр > 0 Цикл
    тЗнач.ПолучитьСтрокуПоНомеру(Стр);
    тЗнач.УдалитьСтроку(Стр);
    Стр = Стр - 1;
    КонецЦикла; 
    Вр2 = ТекущееВремя();
    тЗнач2.ВыбратьСтроки();
    Пока тЗнач2.ПолучитьСтроку() = 1 Цикл
    тЗнач2.УдалитьСтроку();
    КонецЦикла; 
    Вр3 = ТекущееВремя();
    Сообщить(Вр1);
    Сообщить(Вр2);
    Сообщить(Вр3);
    КонецПроцедуры
    Результаты:
    14:06:11
    14:06:12
    14:10:25
    То есть мой вариант отрабатывает всего за секунду даже на 30000 строках, чего не скажешь о "прямом" удалении.
  20. Бухгалтерский угодник
    Offline

    Бухгалтерский угодник Администраторы Команда форума Администратор

    Регистрация:
    29 дек 2008
    Сообщения:
    21.520
    Симпатии:
    407
    Баллы:
    104
    Вы бы хоть отладчиком прошлись сначала.........
    Код:
    Сообщить(тЗнач2.Количествострок()); //=1500

Поделиться этой страницей