Автор Тема: Говнокод  (Прочитано 16078 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Говнокод
« : Июнь 07, 2012, 07:53:24 am »
...
Для каждого СтрокаДетальная из СтрокаОткудаКуда.Строки Цикл
Если СтрокаДетальная.Номенклатура <> ТекНоменклатура ИЛИ СтрокаДетальная.Счет <> ТекСчет ИЛИ СтрокаДетальная.КБК <> ТекКБК Тогда
Продолжить;
КонецЕсли;
...

WTF?

Этот перл мне попался в типовой конфигурации.
"СтрокаОткудаКуда.Строки" содержит 6500000 строк. Все это находится в процедуре, которая вызывается несколько тысяч раз.
Проверку проходят только 300000.
Соответственно 20% времени выполнения тратится на этот код. (а время выполнения 30 мин)

Зачем такое писать, если в 1С есть индексированные коллекции с быстрым поиском??? :o

Жесть.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Говнокод
« Ответ #1 : Июнь 07, 2012, 10:11:45 am »
Я вообще не понял смысла этого кода. Он же вроде ничего не делает. Усеченный аналог:
foreach (i : is) {
    if (condition(i)) continue;
}

Или там после конца если еще какой-то код в теле цикла есть?

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

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #2 : Июнь 07, 2012, 10:52:46 am »
Напоминает классику "лучше день потерять, потом за пять минут долететь"...
Индексировать 6,5 млн строк, вернее составных объектов,  в 1С, видимо, посчитали излишним.
Причины могут быть разными: от банального "к следующему выпуску ИТС поправим (надо же за что-то деньги драть)", до "сортировать 6,5 млн объектов, где каждый реквизит сам себе объект...". Сколько времени займет построение индексированной коллекции из 6,5 млн элементов, может оно не стоит того на таких данных? Откуда появилось 6,5 млн. объектов?

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #3 : Июнь 07, 2012, 11:27:19 am »
Или там после конца если еще какой-то код в теле цикла есть?

Да. Там код в теле цикла.

...
Для каждого СтрокаДетальная из СтрокаОткудаКуда.Строки Цикл
Если СтрокаДетальная.Номенклатура <> ТекНоменклатура ИЛИ СтрокаДетальная.Счет <> ТекСчет ИЛИ СтрокаДетальная.КБК <> ТекКБК Тогда
Продолжить;
КонецЕсли;
... // тут код!
КонецЦикла;
...
« Последнее редактирование: Июнь 07, 2012, 11:30:59 am от ilovb »

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #4 : Июнь 07, 2012, 11:35:57 am »
Напоминает классику "лучше день потерять, потом за пять минут долететь"...
Индексировать 6,5 млн строк, вернее составных объектов,  в 1С, видимо, посчитали излишним.
Причины могут быть разными: от банального "к следующему выпуску ИТС поправим (надо же за что-то деньги драть)", до "сортировать 6,5 млн объектов, где каждый реквизит сам себе объект...". Сколько времени займет построение индексированной коллекции из 6,5 млн элементов, может оно не стоит того на таких данных? Откуда появилось 6,5 млн. объектов?

Ну займет индексирование по трем полям секунды 3, а поиск будет за миллисекунды работать.

DIzer

  • Гость
Re: Говнокод
« Ответ #5 : Июнь 07, 2012, 12:01:26 pm »
Зачем такое писать, если в 1С есть индексированные коллекции с быстрым поиском??? :o

Жесть.
Вопрос риторический и ответ - банальный, в следствие низкой квалификации и/или плохого понимания задачи.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #6 : Июнь 07, 2012, 02:35:18 pm »
Ну займет индексирование по трем полям секунды 3, а поиск будет за миллисекунды работать.
Ну, может 1С с тех пор сильно вперед продвинулась, чтобы упорядочить 6,5 млн объектов за 3 секунды, или у меня комп не шибко быстрый был, я не знаю, но на примерно 2,5 млн объектов по 2-м полям оно ~15 минут работало и память жрало нещадно...

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #7 : Июнь 07, 2012, 04:35:39 pm »
Чего-то я уже сам засомневался. Может нуль лишний привиделся...
Щас запущу расчет и проверю чего там было.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #8 : Июнь 07, 2012, 05:20:43 pm »
Да заработался....
6,5м и 300к - это была статистика из профайлера. Столько раз отработал этот код.

А в коллекции всего около 1000 строк.

Но один фиг суть не меняется. Тем более 1С-ный код работает на моей машине в 500 раз медленнее нативного. А поиск в индексированных коллекциях нативный, и индексы составные можно строить, и строятся они очень быстро.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Говнокод
« Ответ #9 : Июнь 07, 2012, 06:35:27 pm »
Ну может ребята захотели форыч использовать, а как его с индексированной коллекцией юзать? Не помню, у них форыч с первого элемента стартует или с текущего?

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #10 : Июнь 07, 2012, 07:26:38 pm »
Все коллекции в 1с обходятся форычем. Я кстати замерил время построения составного индекса по трем полям в коллекции из 500000 элементов - 0,7 сек

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Говнокод
« Ответ #11 : Июнь 08, 2012, 05:14:29 am »
Кстати, подслушивая разговоры наших 1с-ников (один обучал писать циклы другого) с ужасом узнал, что в 1С в цикле Для (For) нет возможности указать шаг приращения счётчика. Правда что ли вам приходится делать так:

Для I = 1 До 100 Цикл
    <чо-та тут делаем>
    I = I + 3; // шаг цикла = 4 ??? или 3 ???
КонецЦикла
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #12 : Июнь 08, 2012, 06:25:57 am »
Ага  :)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #13 : Июнь 08, 2012, 06:32:22 am »
Но только не в FOR конечно а в WHILE

Делать так в FOR имхо говнокод

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Говнокод
« Ответ #14 : Июнь 08, 2012, 06:43:26 am »
Накидал маленький тест:

Процедура КнопкаВыполнитьНажатие(Кнопка)
   
   Таблица = Новый ТаблицаЗначений;
   Колонки = Таблица.Колонки;
   
   Колонки.Добавить("Раз");
   Колонки.Добавить("Два");
   Колонки.Добавить("Три");
   Колонки.Добавить("Четыре");
   
   Индекс = 0;
   
   Число = 0;
   
   Для Индекс = 0 По 500000 Цикл   
      НоваяСтрока = Таблица.Добавить();
      Если Число > 100 Тогда Число = 0 КонецЕсли;
      НоваяСтрока.Раз = Число; Число = Число + 1;
      НоваяСтрока.Два = Число; Число = Число + 1;
      НоваяСтрока.Три = Число; Число = Число + 1;
      НоваяСтрока.Четыре = Индекс;
   КонецЦикла;
   
   Таблица2 = Таблица.Скопировать();
   
   Таблица.Индексы.Добавить("Раз, Два, Три");
      
   Число = 0;
   Для Индекс = 0 По 1000 Цикл
      
      Если Число > 100 Тогда Число = 0 КонецЕсли;
      Раз = Число; Число = Число + 1;
      Два = Число; Число = Число + 1;
      Три = Число; Число = Число + 1;
            
      ИскомыеСтроки = Таблица.НайтиСтроки(Новый Структура("Раз, Два, Три", Раз, Два, Три));
      
      ИскомыеСтроки = Таблица2.НайтиСтроки(Новый Структура("Раз, Два, Три", Раз, Два, Три));
      
      Обработать1(Таблица, Новый Структура("Раз, Два, Три", Раз, Два, Три));
      
      Обработать2(Таблица, Раз, Два, Три);
      
   КонецЦикла;
   
КонецПроцедуры

Процедура Обработать1(Таблица, Отбор) // мой способ
   
   ИскомыеСтроки = Таблица.НайтиСтроки(Отбор);
   
   Для Каждого ТекСтрока Из ИскомыеСтроки Цикл
      Рез = ТекСтрока.Четыре / 2; // какой-то код
   КонецЦикла;
   
КонецПроцедуры

Процедура Обработать2(Таблица, Раз, Два, Три) // способ с "Продолжить"
   
   Для Каждого ТекСтрока Из Таблица Цикл
      
      Если ТекСтрока.Раз <> Раз ИЛИ ТекСтрока.Два <> Два ИЛИ ТекСтрока.Три <> Три Тогда
         Продолжить;
      КонецЕсли;
      
      Рез = ТекСтрока.Четыре / 2; // какой-то код
      
   КонецЦикла;
   
КонецПроцедуры


Статистика профайлера:
http://smotr.im/5idz