- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 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);
Я знаю, что рекурсивный крестошаблон сможет сделать то же самое, но крестопортянка всё равно быстрее пишется и выглядит нагляднее.
Так-то ты документируешь свои игрульки...?
Этот параметр участвует в выражениях во внутреннем цикле отрисовки, почему-то я решил, что пиздец как важно, чтобы он был константой, так как иначе типа лишние вычисления будут делаться, но почему я так решил - не помню.
КРЕСТООПТИМИЗАЦИЯ
Хотя я хотел сделать две специализации для функции определения расстояния - точный расчёт и неточный (вы видели ту функцию), но здравый смысл победил крестоблядский рефлекс - достаточно было вставить одну незначительную проверку, чтобы городить эту херню было не надо.
Не так.
// ОЛОЛО ОЛОЛО КРЕСТОБЛЯДСКОЕ ХУЙЛО
http://govnokod.ru/7095#comment94231
Дай дураку шаблоны так он хуйню напишет.
их Тарас по дешевке где то в интернетах накопал - тут хвастался
см. старые говнокоды Тараса, в которых он рассказывал о библиотеке для чисел с фиксированной точкой.
Ещё я мог написать 1.0 вместо Fixed(1), тогда компилятор не будет дизамбиговаться, но будет делать ненужные вычисления с нахуй не усравшейся тут плавающей запятой.
Всё-таки, хорошо, когда фиксированная запятая вшита в язык заранее, да, я снова про Аду.
Вот есть некая функция, и код этой функции таков, что если один из параметров - константа, известная при кокомпиляции, то функция внезапно ускоряется.
И как бы надо сделать так, чтобы все эти предрасчёты выбирались заранее и заранее выбирался вариант функции, оптимизированный под нужное значение.
Поэтому как бы можно ускорить программу, если сей параметр запихать в шаблололон и вызывать как-то так:
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 как аргумента функции
Если передавать константу - то сработает как шаблон.
В общем нужен какой-то способ намекнуть компилятору, что очень важно заранее провести все вычисления, связанные с таким-то параметром и что этот самый параметр может принимать такой-то набор значений.
такое случается крайне редко
ты считаешь, что оптимизатор не разберется с целочисленным аргументом?
2) Воспользоваться SDL/OpenGL/чтонибудьеще где годами задрачивали производительность под каждую платформу, и не рисовать круги самому.
2. Еретик
да этож байтоебство какое-то. Шаблоны нужны, в основном, для генерации однотипного кода
> она[Ада] тупо воспримет этот параметр шаблона как параметр функции.
в аде типы и шаблоны - объекты первого класса?
А байтоёбство иногда нужно, да, главное не увлекаться, а то кресты очень провоцируют.
Я правда не нашел красивого способа выхода из for_each кроме как кинуть эксепшн.
И еще я осознал, что у меня получился еще больший говнокод чем у автора :(
тут дело в том, что, например, для i == 5 (без преждевременного выхода из цикла) круг будет рисоваться для <5>, <6>, <7>, <8>
вместо throw можно сделать флаг-член bool done_, либо приладить иной mpl алгоритм (а не for_each)
HaskellGovno в комментах ерунду выдаёт...
что это за директива такая?
Perform function cloning to make interprocedural constant propagation stronger. When enabled, interprocedural constant propagation will perform function cloning when externally visible function can be called with constant arguments. Because this optimization can create multiple copies of functions, it may significantly increase code size (see --param ipcp-unit-growth=value). This flag is enabled by default at -O3.
[ b ][ /b ]
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;
(только нельзя инициализировать шаблоны на месте, надо заранее объявлять все инициализации, но суть не меняется).
В крестах для того же самого придётся ээээ передавать крестошабллонный крестокласс, с крестооперотором, возвращающим либо константу (и который заинлайнится и станет вести себя как тупо число) либо значение переменной (который заинлайнится, но будет вести себя как переменная).
"в данном случае" - а в каком же случае использование данного "паттерна" даст осмысленный выигрыш в производительности?
А случаи, когда константность позволяет убрать лишние ветки, деления и вообще дохрена операций лишних убрать - есть.
Все ясно, вопрос исчерпан.
Вполне реально, что выбрать стратегию нужно в момент исполнения. Хотя приличные программисты помнят, что в С++ существуют основанные на ОО возможности сокрытия сложности реализации сложностью структуры.
Но вот что, всё же, подразумевал Тарас?