Обсуждение участника:ArmorAdmin/Говнокод — различия между версиями

Материал из Бронетанковой Энциклопедии — armor.kiev.ua/wiki
Перейти к: навигация, поиск
м (LostArtilleryMan переименовал страницу Обсуждение участника:ГОВНЮК/Говнокод в Обсуждение участника:ArmorAdmin/Говнокод поверх перенаправления…)
 
(не показано 5 промежуточных версий 3 участников)
Строка 30: Строка 30:
 
</pre>
 
</pre>
  
В моё студенческое время она предлагалась учащимся на втором семестре первого курса. И 99% решений, переложенным на реалии сегодняшнего PHP выглядело примерно так:
+
В моё студенческое время она предлагалась учащимся на втором семестре первого курса. И 99% решений, переложенные на реалии сегодняшнего PHP выглядели примерно так:
  
 
<source lang="php">
 
<source lang="php">
Строка 51: Строка 51:
 
</source>
 
</source>
  
Что плохого — быстрые компьютеры делают незаметным тот факт, что степень считается медленнее, чем все остальные операции. К примеру, на имеющемся в распоряжении Web-сервере HP Proliant ML370 за 10 секунд процессор сумел сделать 3&nbsp;496&nbsp;404 итерации в цикле с единственной полезной нагрузкой — возвести одно число в некую степень, тогда как за то же время он способен сделать 4&nbsp;793&nbsp;630 умножений и 7&nbsp;023&nbsp;658 итераций цикла без полезной нагрузки (только инкремент счётчика и анализ условия на своё окончание). Таким образом чисто на служебные операции уходит 1,42 мкс, на вычисление степени — 1,44 мкс, а на чистое перемножение — 0,67 мкс. Для учебного примера некритично, но когда дело доходит до серьёзных расчётов, имитационного моделирования или действий в реальном времени на ограниченных по ресурсам системах — дело плохо!
+
Что плохого — быстрые компьютеры делают незаметным тот факт, что степень считается медленнее, чем все остальные операции. К примеру, на имеющемся в распоряжении Web-сервере HP Proliant ML370 за 10 секунд процессор сумел сделать 3&nbsp;496&nbsp;404 итерации в цикле с единственной полезной нагрузкой — возвести одно число в некую степень, тогда как за то же время он способен сделать 4&nbsp;793&nbsp;630 умножений и 7&nbsp;023&nbsp;658 итераций цикла без полезной нагрузки (только инкремент счётчика и анализ условия на своё окончание). Таким образом чисто на служебные операции за одну итерацию цикла уходит 1,42 мкс, на вычисление степени — 1,44 мкс, а на чистое перемножение — 0,67 мкс. Для учебного примера некритично, но когда дело доходит до серьёзных расчётов, имитационного моделирования или действий в реальном времени на ограниченных по ресурсам системах — дело плохо!
  
 
А теперь посмотрим, что можно сделать. Если чуть-чуть приглядеться к формуле, то мы увидим, что каждый её член z<sub>n</sub> связан с последующим ну очень простым соотношением:
 
А теперь посмотрим, что можно сделать. Если чуть-чуть приглядеться к формуле, то мы увидим, что каждый её член z<sub>n</sub> связан с последующим ну очень простым соотношением:
Строка 67: Строка 67:
 
function sin_tailor($x, $eps)
 
function sin_tailor($x, $eps)
 
{
 
{
   $sn = $x; $s = $x; $x2 = $x * $x; $n = 3;  
+
   $sn = $x; $s = $x; $x2 = $x * $x; $n = 1;  
 
   do
 
   do
 
   {
 
   {
 +
    $n  = $n + 2;
 
     $sn = -$sn * $x2 / $n / ($n - 1);
 
     $sn = -$sn * $x2 / $n / ($n - 1);
 
     $sp = $s;
 
     $sp = $s;
 
     $s += $sn;
 
     $s += $sn;
    $n = $n + 2;
 
 
   }
 
   }
 
   while (abs($sp - $s) > $eps);
 
   while (abs($sp - $s) > $eps);
Строка 81: Строка 81:
  
 
В результате на тот же сервер за те же 10 секунд рассчитал для x = 0,4 и ε = 10<sup>8</sup> по первой реализации синус с заданной точностью 134&nbsp;883 раз, а по второму — 465&nbsp;614. Разница очевидна, не правда ли? Вывод прост — работа над хорошим кодом всегда начинается с обдумывания алгоритма.
 
В результате на тот же сервер за те же 10 секунд рассчитал для x = 0,4 и ε = 10<sup>8</sup> по первой реализации синус с заданной точностью 134&nbsp;883 раз, а по второму — 465&nbsp;614. Разница очевидна, не правда ли? Вывод прост — работа над хорошим кодом всегда начинается с обдумывания алгоритма.
 +
 +
: Анатолий, это уже слишком глубоко. Говнокодеры работают на другом, примитивном уровне, а оптимизация алгоритмов и быстродействия — для другой аудитории :))) --[[Участник:ArmorAdmin|Чобиток Василий]] 14:18, 27 августа 2010 (UTC)

Текущая версия на 03:47, 20 декабря 2015

Пример №2

Кстати, почему бы не сделать так:

$imgCreateMethods = array (
    IMAGETYPE_GIF => 'gif',
    IMAGETYPE_JPEG => 'jpeg',
    IMAGETYPE_PNG => 'png',
);
 
$fun = 'imagecreatefrom' . $imgCreateMethods[$imgType];
$img = $fun($image_path);

Вледельцу сайта в принципе необязательно знать ПХПовы имена функций, а поскольку они унифицированы и новые будущие почти наверняка будут придерживаться того же соглашения об именовавании, то достаточно в конфиге оставить только понятно-расширенческую часть, без imagecreatefrom оно доступнее для понимания выглядит. LostArtilleryMan 03:56, 17 августа 2010 (UTC)

Ты не поверишь. Чесались руки дать именно такой вариант. Исходил из соображений: во-1-х всё же нет гарантии, что именование других подобных функций будет построено по этой же схеме, во-2-х владелец сайта сам по себе решать что-то добавлять или удалять не будет, ему будут соответствующие инструкции. А на уровне инструкции «добавьте туда-то строчку IMAGETYPE_PNG => 'imagecreatefrompng',» или «добавьте туда-то строчку IMAGETYPE_PNG => 'png',» — для владельца сайта одинаково «понятно». И в моем варианте читабельность для программиста остается — суть массива в указании функций создания картинок указанных форматов, а в твоём типу на первый взгляд соответствует расширение (?) и смысл применения массива надо уже по коду искать.
Это я, кстати, делаю движок работы с галереями картинок (загрузка пользователями). Делаю не с нуля, взял за основу http://sourceforge.net/projects/dir-list/ но кардинально переделываю, пока только чистый рефакторинг, код хоть и понятный, несложный и с комментариями, но говнокода дофига. Например, практически идентичный код создания картинок уменьшенного размера повторяется в трех разных файлах с минимальными изменениями — я ввёл единый класс, отвечающий за изменение размеров и в этих файлах сократил код обращением к классу. Закончу рефакторинг, буду делать новый функционал (управление галереями юзеров, навигация по галереям и пр.). --Чобиток Василий 10:40, 17 августа 2010 (UTC)

Вспоминайте иногда бедного студента...

Тривиальная задача — рассчитать значение синуса некоей величины, выраженной в радианах через ряд Тейлора с точностью ε:

              3   5   7                  n   
             x   x   x           [n/2]  x
sin(x) = x - — + — - — + … + (-1)     * — + …   
             3!  5!  7!                 n!

где n   — арифметическая прогрессия нечётных целых чисел 1, 3, 5, 7, … 
    [y] — операция определения целой части от y.

В моё студенческое время она предлагалась учащимся на втором семестре первого курса. И 99% решений, переложенные на реалии сегодняшнего PHP выглядели примерно так:

function sin_tailor($x, $eps)
{
  $s = 0.0; $n = 1;
  do
  {
    $nfact = 1;
    for ($i = 2; $i <= $n; $i++)
      $nfact *= $i;
    $sp = $s;
    $s += pow(-1, floor($n / 2)) * pow($x, $n) / $nfact;
    $n = $n + 2;
  }
  while (abs($sp - $s) > $eps);
  return $s;
}

Что плохого — быстрые компьютеры делают незаметным тот факт, что степень считается медленнее, чем все остальные операции. К примеру, на имеющемся в распоряжении Web-сервере HP Proliant ML370 за 10 секунд процессор сумел сделать 3 496 404 итерации в цикле с единственной полезной нагрузкой — возвести одно число в некую степень, тогда как за то же время он способен сделать 4 793 630 умножений и 7 023 658 итераций цикла без полезной нагрузки (только инкремент счётчика и анализ условия на своё окончание). Таким образом чисто на служебные операции за одну итерацию цикла уходит 1,42 мкс, на вычисление степени — 1,44 мкс, а на чистое перемножение — 0,67 мкс. Для учебного примера некритично, но когда дело доходит до серьёзных расчётов, имитационного моделирования или действий в реальном времени на ограниченных по ресурсам системах — дело плохо!

А теперь посмотрим, что можно сделать. Если чуть-чуть приглядеться к формуле, то мы увидим, что каждый её член zn связан с последующим ну очень простым соотношением:

                     2
                    x
  z    = -z  * ———————————
   n+1     n   n * (n - 1) 

И, не претендуя на идеальность программы, сразу получим более быстрый её вариант

function sin_tailor($x, $eps)
{
  $sn = $x; $s = $x; $x2 = $x * $x; $n = 1; 
  do
  {
    $n  = $n + 2;
    $sn = -$sn * $x2 / $n / ($n - 1);
    $sp = $s;
    $s += $sn;
  }
  while (abs($sp - $s) > $eps);
  return $s;
}

В результате на тот же сервер за те же 10 секунд рассчитал для x = 0,4 и ε = 108 по первой реализации синус с заданной точностью 134 883 раз, а по второму — 465 614. Разница очевидна, не правда ли? Вывод прост — работа над хорошим кодом всегда начинается с обдумывания алгоритма.

Анатолий, это уже слишком глубоко. Говнокодеры работают на другом, примитивном уровне, а оптимизация алгоритмов и быстродействия — для другой аудитории :))) --Чобиток Василий 14:18, 27 августа 2010 (UTC)