1. C++ / Говнокод #11479

    +18

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    // ОЛОЛО ОЛОЛО КРЕСТОШАБЛОНЫ И ХУЙЛО
     if (ro<Fixed(100))
         DrawCircle<0>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(200))
         DrawCircle<1>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(400))
         DrawCircle<2>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(800))
         DrawCircle<3>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(1600))
         DrawCircle<4>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(3200))
         DrawCircle<5>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(6400))
         DrawCircle<6>(b, x, y, ri, ro, ball.color);
     else if (ro<Fixed(12800))
         DrawCircle<7>(b, x, y, ri, ro, ball.color);
     else
         DrawCircle<8>(b, x, y, ro, ri, ball.color);

    Я знаю, что рекурсивный крестошаблон сможет сделать то же самое, но крестопортянка всё равно быстрее пишется и выглядит нагляднее.

    Запостил: TarasB, 26 Июля 2012

    Комментарии (67) RSS

    • > // ОЛОЛО ОЛОЛО КРЕСТОШАБЛОНЫ И ХУЙЛО
      Так-то ты документируешь свои игрульки...?
      Ответить
    • А можно взглянуть на код DrawCircle?
      Ответить
      • Там суть в том, что этот параметр задаёт точность отрисовки. Если рисовать большой радиус с высокой точностью, то будет целочисленное переполнение и исключение (размечтались, в крестоблядких языках нет такой проверки) и некорректный результат.
        Этот параметр участвует в выражениях во внутреннем цикле отрисовки, почему-то я решил, что пиздец как важно, чтобы он был константой, так как иначе типа лишние вычисления будут делаться, но почему я так решил - не помню.
        Ответить
        • >важно, чтобы он был константой, но почему я так решил - не помню

          КРЕСТООПТИМИЗАЦИЯ
          Ответить
        • Используется для предделения чисел, перед их умножением? Аля эмуляция флоата...
          Ответить
      • будет самый сок, если каждый <N> там - специализация
        Ответить
        • Нет, такими веществами я ещё не упарывался.
          Хотя я хотел сделать две специализации для функции определения расстояния - точный расчёт и неточный (вы видели ту функцию), но здравый смысл победил крестоблядский рефлекс - достаточно было вставить одну незначительную проверку, чтобы городить эту херню было не надо.
          Ответить
    • > // ОЛОЛО ОЛОЛО КРЕСТОШАБЛОНЫ И ХУЙЛО
      Не так.
      // ОЛОЛО ОЛОЛО КРЕСТОБЛЯДСКОЕ ХУЙЛО
      Ответить
      • Так он эту фразу отсюда взял:
        http://govnokod.ru/7095#comment94231
        Ответить
    • Я ебал...
      Дай дураку шаблоны так он хуйню напишет.
      Ответить
    • Наркоман штоле?
      Ответить
    • Чего линейный поиск используешь в цепочке ифов? Хоть деление случаев пополам используй чтоли.
      Ответить
      • По причине перекоса вероятности значения в сторону маленьких чисел.
        Ответить
    • Что возвращает Fixed?
      Ответить
      • очевидно божественные числа с фиксированной точкой
        их Тарас по дешевке где то в интернетах накопал - тут хвастался
        Ответить
      • Объект класса Fixed.

        см. старые говнокоды Тараса, в которых он рассказывал о библиотеке для чисел с фиксированной точкой.
        Ответить
        • Возможно, 'ro<Fixed(n)' должно происходить внутри Fixed и возвращать целые для шаблона?
          Ответить
          • Это просто приведение целого к фикседу
            Ещё я мог написать 1.0 вместо Fixed(1), тогда компилятор не будет дизамбиговаться, но будет делать ненужные вычисления с нахуй не усравшейся тут плавающей запятой.
            Всё-таки, хорошо, когда фиксированная запятая вшита в язык заранее, да, я снова про Аду.
            Ответить
            • А почему нельзя написать просто ro < 100? В либе, если не ошибаюсь, вроде бы были перегруженные операторы сравнения для интов и флоатов.
              Ответить
              • видать из-за операторов к инту и флоату компилятор был неуверен в адекватности происходящего (ro приводить к int или наоборот) и постоянно переспрашивал
                Ответить
              • Потому что компилятор дизамбигнётся.
                Ответить
    • Вообще суть сего потырна такова.
      Вот есть некая функция, и код этой функции таков, что если один из параметров - константа, известная при кокомпиляции, то функция внезапно ускоряется.
      И как бы надо сделать так, чтобы все эти предрасчёты выбирались заранее и заранее выбирался вариант функции, оптимизированный под нужное значение.
      Поэтому как бы можно ускорить программу, если сей параметр запихать в шаблололон и вызывать как-то так:
      switch(i){
      case 1 : return func<1>(a,b,c);
      case 2 : return func<2>(a,b,c);
      case 3 : return func<3>(a,b,c);
      case 4 : return func<4>(a,b,c);
      case 5 : return func<5>(a,b,c);
      ...
      }
      И всё это вместо простого return func<i>(a,b,c).
      И тут бы самое время потроллить про крестоблядский язык С++, который не может переменные в параметры шаблона, а вот Ада может, но Ада же не генерирует этот свич в таких случаях - она тупо воспримет этот параметр шаблона как параметр функции.
      В общем, как сей потырн нормально реализовать, я придумать не могу.
      Ответить
      • самое время потроллить - ведь ада не может в специализации
        т.е. такой адоблядский генерик не имеет никаких преимуществ перед крестоблядской передачей int как аргумента функции
        Ответить
        • Если передавать переменную - да, преимуществ нету.
          Если передавать константу - то сработает как шаблон.
          В общем нужен какой-то способ намекнуть компилятору, что очень важно заранее провести все вычисления, связанные с таким-то параметром и что этот самый параметр может принимать такой-то набор значений.
          Ответить
          • подобные пассажи со свичом надобно делать, когда шаблоны от size_t действительно очень разные (и скорее всего, специализированы)
            такое случается крайне редко
            Ответить
            • Да даже если и одинаковые и параметр этот как-то используется в ресурсоёмких операциях.
              Ответить
              • шаблон отшаблонить от float нельзя
                ты считаешь, что оптимизатор не разберется с целочисленным аргументом?
                Ответить
                • Да даже если и отцелого, то да, оптимизатор, конечно же не разберётся - если он не константа, то откуда оптимизатору знать, что надо сделать 8 копий с константой и выбрать одну из них исходя из значения этого числа? Он же не телепат, нужно ему как-то явно это указать.
                  Ответить
                  • напиши уже просто бенчмарк и сравни производительность в обоих случаях
                    Ответить
                    • Специальный тест ты и сам можешь придумать, потому что суть и так понятна, я думаю
                      Ответить
      • Имхо преждевременная оптимизация. Если эта константа потом используется в делении, то производительность не должна упасть, в случае если мы внесем пачку ифов внутрь DrawCircle, где она будет заполнять переменную. Ну не должна операция с регистром быть намного медленее операции с константой...
        Ответить
        • Ну вот допустим, она используется в делении и во внутреннем цикле. И какие способы оптимизировать?
          Ответить
          • 1) Надеяться на то, что компилятор поместит переменную в регистр (а хороший компилятор ее туда поместит, т.к. она часто используется во внутреннем цикле).
            2) Воспользоваться SDL/OpenGL/чтонибудьеще где годами задрачивали производительность под каждую платформу, и не рисовать круги самому.
            Ответить
            • 1. Да толку от деления на регистр, если для константы можно не делить вообще?
              2. Еретик
              Ответить
      • >Поэтому как бы можно ускорить программу, если сей параметр запихать в шаблололон и вызывать как-то так:

        да этож байтоебство какое-то. Шаблоны нужны, в основном, для генерации однотипного кода

        > она[Ада] тупо воспримет этот параметр шаблона как параметр функции.

        в аде типы и шаблоны - объекты первого класса?
        Ответить
        • Что такое "объект 1го класса"?
          А байтоёбство иногда нужно, да, главное не увлекаться, а то кресты очень провоцируют.
          Ответить
    • Use MPL, Luke :)

      #include <boost/mpl/pair.hpp>
      #include <boost/mpl/for_each.hpp>
      #include "boost/mpl/range_c.hpp"
      
      #include <iostream>
      
      int Fixed(int a) {}
      
      using namespace boost::mpl;
      
      constexpr int range_max(int i) {
          return (1 << i) * 100;
      }
      
      struct stop_iteration {};
      
      class circle_drawer
      {
          int& ro;
      
      public:
          circle_drawer(int& ro_) : ro(ro_) {}
          
          template< typename U > 
          void operator()(U i)
          {
              if( i == 8 || ro < Fixed(range_max(i)) ) {
                  DrawCircle<U::value>(b, x, y, ri, ro, ball.color);
                  
                  throw stop_iteration();
              }
          }
      };
      
      int main() {
          int ro = 800;
          
          try {
              for_each< range_c<int, 0, 8> >( circle_drawer(ro) );
          }
          catch(stop_iteration& si) {}
      }


      Я правда не нашел красивого способа выхода из for_each кроме как кинуть эксепшн.
      И еще я осознал, что у меня получился еще больший говнокод чем у автора :(
      Ответить
      • Выходи из цикла специализацей для i=8
        Ответить
        • КРЕСТОПАТТЕРНЫ
          Ответить
        • специализация тут не причем
          тут дело в том, что, например, для i == 5 (без преждевременного выхода из цикла) круг будет рисоваться для <5>, <6>, <7>, <8>
          вместо throw можно сделать флаг-член bool done_, либо приладить иной mpl алгоритм (а не for_each)
          Ответить
    • gcc -fipa-cp-clone не спасёт Тараса?
      Ответить
    • ну и каков реальный выигрыш в производительности от такого изврата по сравнению с просто
      DrawCircle<i>(b, x, y, ri, ro, ball.color);
      и с
      DrawCircle(i, b, x, y, ri, ro, ball.color);
      ?
      Ответить
      • В данном случае копеечный.
        Но мы обсуждаем данный паттерн в целом, а не только для данного случая.
        Кстати, в Аде можно примерно так:
        if i=0 then DrawCircle<0>(b,x,y,ri,ro,ball.color); // вероятный случай, нужна скорость
        else DrawCircle<i>(b,x,y,ri,ro,ball.color); // маловероятный случай скорость пох
        end if;
        (только нельзя инициализировать шаблоны на месте, надо заранее объявлять все инициализации, но суть не меняется).
        В крестах для того же самого придётся ээээ передавать крестошабллонный крестокласс, с крестооперотором, возвращающим либо константу (и который заинлайнится и станет вести себя как тупо число) либо значение переменной (который заинлайнится, но будет вести себя как переменная).
        Ответить
        • "копеечный" - это, я так понимаю, 0.000000001%? другими словами - меньше погрешности тайминга?

          "в данном случае" - а в каком же случае использование данного "паттерна" даст осмысленный выигрыш в производительности?
          Ответить
          • Я не замерял, полагаю, что меньше 5%.
            А случаи, когда константность позволяет убрать лишние ветки, деления и вообще дохрена операций лишних убрать - есть.
            Ответить
    • Байто@бов тред.
      Ответить
      • Странное у тебя емыло, что это за почтовый сервис такой - бов.тред?
        Ответить
    • Вполне реальная ситуация, когда существует множество специализированных шаблонов для разных параметров или шаблон сложным образом инстанцируется от параметра. Для таких случаев очень удобны шаблоны. Только приличные программисты используют говорящие имена из перечислений.
      Вполне реально, что выбрать стратегию нужно в момент исполнения. Хотя приличные программисты помнят, что в С++ существуют основанные на ОО возможности сокрытия сложности реализации сложностью структуры.

      Но вот что, всё же, подразумевал Тарас?
      Ответить

    Добавить комментарий