Обсуждение участника:ArmorAdmin/Говнокод — различия между версиями
(→Пример №2) |
|||
Строка 17: | Строка 17: | ||
: Ты не поверишь. Чесались руки дать именно такой вариант. Исходил из соображений: во-1-х всё же нет гарантии, что именование других подобных функций будет построено по этой же схеме, во-2-х владелец сайта сам по себе решать что-то добавлять или удалять не будет, ему будут соответствующие инструкции. А на уровне инструкции «''добавьте туда-то строчку '''IMAGETYPE_PNG => 'imagecreatefrompng','''''» или «''добавьте туда-то строчку '''IMAGETYPE_PNG => 'png','''''» — для владельца сайта одинаково «понятно». И в моем варианте читабельность для программиста остается — суть массива в указании функций создания картинок указанных форматов, а в твоём типу на первый взгляд соответствует расширение (?) и смысл применения массива надо уже по коду искать. | : Ты не поверишь. Чесались руки дать именно такой вариант. Исходил из соображений: во-1-х всё же нет гарантии, что именование других подобных функций будет построено по этой же схеме, во-2-х владелец сайта сам по себе решать что-то добавлять или удалять не будет, ему будут соответствующие инструкции. А на уровне инструкции «''добавьте туда-то строчку '''IMAGETYPE_PNG => 'imagecreatefrompng','''''» или «''добавьте туда-то строчку '''IMAGETYPE_PNG => 'png','''''» — для владельца сайта одинаково «понятно». И в моем варианте читабельность для программиста остается — суть массива в указании функций создания картинок указанных форматов, а в твоём типу на первый взгляд соответствует расширение (?) и смысл применения массива надо уже по коду искать. | ||
: Это я, кстати, делаю движок работы с галереями картинок (загрузка пользователями). Делаю не с нуля, взял за основу http://sourceforge.net/projects/dir-list/ но кардинально переделываю, пока только чистый рефакторинг, код хоть и понятный, несложный и с комментариями, но говнокода дофига. Например, практически идентичный код создания картинок уменьшенного размера повторяется в трех разных файлах с минимальными изменениями — я ввёл единый класс, отвечающий за изменение размеров и в этих файлах сократил код обращением к классу. Закончу рефакторинг, буду делать новый функционал (управление галереями юзеров, навигация по галереям и пр.). --[[Участник:ArmorAdmin|Чобиток Василий]] 10:40, 17 августа 2010 (UTC) | : Это я, кстати, делаю движок работы с галереями картинок (загрузка пользователями). Делаю не с нуля, взял за основу http://sourceforge.net/projects/dir-list/ но кардинально переделываю, пока только чистый рефакторинг, код хоть и понятный, несложный и с комментариями, но говнокода дофига. Например, практически идентичный код создания картинок уменьшенного размера повторяется в трех разных файлах с минимальными изменениями — я ввёл единый класс, отвечающий за изменение размеров и в этих файлах сократил код обращением к классу. Закончу рефакторинг, буду делать новый функционал (управление галереями юзеров, навигация по галереям и пр.). --[[Участник:ArmorAdmin|Чобиток Василий]] 10:40, 17 августа 2010 (UTC) | ||
+ | |||
+ | == Вспоминайте иногда бедного студента... == | ||
+ | Тривиальная задача — рассчитать значение синуса некоей величины, выраженной в радианах через ряд Тейлора с точностью ε: | ||
+ | <pre> | ||
+ | 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. | ||
+ | </pre> | ||
+ | |||
+ | В моё студенческое время она предлагалась учащимся на втором семестре первого курса. И 99% решений, переложенным на реалии сегодняшнего PHP выглядело примерно так: | ||
+ | |||
+ | <source lang="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; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Что плохого — быстрые компьютеры делают незаметным тот факт, что степень считается медленнее, чем все остальные операции. К примеру, на имеющемся в распоряжении Web-сервере HP Proliant ML370 за 10 секунд процессор сумел сделать 3 496 404 итерации в цикле с единственной полезной нагрузкой — возвести одно число в некую степень, тогда как за то же время он способен сделать 4 793 630 умножений и 7 023 658 итераций цикла без полезной нагрузки (только инкремент счётчика и анализ условия на своё окончание). Таким образом чисто на служебные операции уходит 1,42 мкс, на вычисление степени — 1,44 мкс, а на чистое перемножение — 0,67 мкс. Для учебного примера некритично, но когда дело доходит до серьёзных расчётов, имитационного моделирования или действий в реальном времени на ограниченных по ресурсам системах — дело плохо! | ||
+ | |||
+ | А теперь посмотрим, что можно сделать. Если чуть-чуть приглядеться к формуле, то мы увидим, что каждый её член z<sub>n</sub> связан с последующим ну очень простым соотношением: | ||
+ | <pre> | ||
+ | 2 | ||
+ | x | ||
+ | z = -z * ——————————— | ||
+ | n+1 n n * (n - 1) | ||
+ | </pre> | ||
+ | |||
+ | И, не претендуя на идеальность программы, сразу получим более быстрый её вариант | ||
+ | |||
+ | <source lang="php"> | ||
+ | |||
+ | function sin_tailor($x, $eps) | ||
+ | { | ||
+ | $sn = $x; $s = $x; $x2 = $x * $x; $n = 3; | ||
+ | do | ||
+ | { | ||
+ | $sn = -$sn * $x2 / $n / ($n - 1); | ||
+ | $sp = $s; | ||
+ | $s += $sn; | ||
+ | $n = $n + 2; | ||
+ | } | ||
+ | while (abs($sp - $s) > $eps); | ||
+ | return $s; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | В результате на тот же сервер за те же 10 секунд рассчитал для x = 0,4 и ε = 10<sup>8</sup> по первой реализации синус с заданной точностью 134 883 раз, а по второму — 465 614. Разница очевидна, не правда ли? Вывод прост — работа над хорошим кодом всегда начинается с обдумывания алгоритма. |
Версия 12:12, 26 августа 2010
Пример №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 = 3;
do
{
$sn = -$sn * $x2 / $n / ($n - 1);
$sp = $s;
$s += $sn;
$n = $n + 2;
}
while (abs($sp - $s) > $eps);
return $s;
}
В результате на тот же сервер за те же 10 секунд рассчитал для x = 0,4 и ε = 108 по первой реализации синус с заданной точностью 134 883 раз, а по второму — 465 614. Разница очевидна, не правда ли? Вывод прост — работа над хорошим кодом всегда начинается с обдумывания алгоритма.