1. PHP / Говнокод #5040

    +168

    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
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    function getAlphabetList($list = null)
    {   
        $alphabet = split(' ', 'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z');
    
        foreach($alphabet as $letter)
        {
            $has_letter = false;
            if(is_array($list))
            {
                foreach ($list as $value) 
                {
                        if(substr(strtoupper($value),0,1) == strpos($letter,$value,1))
                        {
                            $has_letter = true;
                        }                   
                }
            }
            
            if($has_letter)
            {               
                $output .= '<a href="?letter='.$letter.'">'.$letter.'</a> ';
            } else {
                $output .= $letter.' ';
            }
        }
        return $output;
    }

    Шерстим список записей, определяем, на какие буквы они начинаются, и для имеющихся букв генерируем гиперссылки. Мужика попросили разобраться, почему каталог на 126000 записей тормозит при отображении, и он увидел в коде это.
    http://thedailywtf.com/Articles/Thorough-Letter-Checking.aspx

    Запостил: telnet, 24 Декабря 2010

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

    • Автора выгнать из профессии!
      Ответить
      • А всё почему? В Паскале нет такого ужасного элемента как foreach. Если бы автор писал на Паскале, то ему бы пришлось немного подумать и он заметил бы, что что-то не так.

        P. S. А в PHP после $has_letter = true; нельзя сделать преждевременный выход из цикла?
        Ответить
    • Неужели база данных выплёвывала все 126 тысяч записей в лист?
      Или может в лист, там... десять -- двадцать... по какому-нибудь ещё параметру выплёвывалось?
      Ответить
      • Алгоритм можно ускорить в 26 раз. Ваш К.О.
        Ответить
        • Теоретически при построении отображения вам нужно проделать A*B операций, где A и B мощности множеств.
          На самом же деле мы можем построить заранее карту для одного из множеств, то есть отображение из AxB либо в A, либо в B, тогда совершив только либо B, либо A действий, соответственно.

          Потому построив карту для списка алгоритм можно ускорить в 126, 000 раз.

          В 26 раз он ускоряется, если построена карта для букв (какой-нибудь hashMap в виде ассоциативного массива).
          Ответить
          • Для построения карт тоже нужно время. Пока вроде бы речь шла о данном куске кода, цель которого всего лишь убедиться, что в списке есть хотя бы одна запись на данную букву алфавита и если есть, то оформить её гиперссылкой. Хотя для программы в целом карты бы пригодились.
            Ответить
            • Ну... Просто... Вы говорили, что очевидно можно ускориться в 26 раз.
              Я пояснил, что если в 26 раз именно очевидно, то и в сто тысяч очевидно.

              Автор кода, боюсь, вообще не имеет понятия об отображениях, картах, индексах и т.п.
              Вот я как подумал...
              Ответить
              • Насчёт 100К не понял.
                Каждому элементу списка соответствует одна буква, причём очевидно, какая.
                Но каждой букве соответствует дохрена элементов, то есть карта неочевидна, её нужно строить и... данный ГК это и делает.
                Ответить
                • Если ты хочешь отобразить одну запись в ссылку, то тебе нужно совершить 26 операций: каждой букве дать соответствие либо ноль, либо один. Часто это выражается в несколько иных формах, которые прозрачны для программиста, например: прочесать список ссылок на предмет того, что ссылка уже есть, либо её нужно создать. Однако, можно этот процесс ускорить.
                  Можно заранее построить некоторую "функцию отображения" букв во множество ссылок. Такая функция задаст "карту". Ещё эти функции называют хеш-функциями, по ключу они находят значение. Ключ -- буква, значение -- наличие ссылки. И за одну операцию можно будет выполнить получение ссылки из записи.
                  Так в 26 раз ускоряется.

                  Но можно такую же карту построить и для записей.
                  Так же, как заранее создаётся карта букв, можно заранее создать таблицу, например, в базе данных (такая таблица может носить название "индексной таблицы"), которая будет хранить информацию о том, сколько записей начинается на данную букву. Эта таблица будет содержать всего 26 записей. И для построения ссылок нужно будет пройтись по этой таблице всего один раз, тем самым получив ускорение в 126 000 раз.

                  Операция построения этих карт совершенно симметрична относительно того на чём её строить (на буквах или на записях) с точки зрения математики. С точки зрения диспетчеризации, конечно не одно и тоже. Ибо: алфавит статичен, а записи меняются, и карту записей придётся чаще обновлять. Но разве столь существенное ускорение не стоит того?
                  Ответить
                  • > Но можно такую же карту построить и для записей.

                    Что и делает данный код!
                    Ответить
                    • Код строит полноценное отображение каждый раз, не используя предвычисленных карт ни для букв, ни для записей.
                      И вот ускорить его можно, если: либо шерстить записи и, выбирая первую букву, по карте (выраженной ассоциативным массивом, например) сразу создавать ссылку, либо шерстить буквы и по предвычисленной карте уже для записей (выраженной, например, индексной таблицей) получать сразу ссылку.

                      Возможно, я не могу правильно мысль преподнести...
                      Ответить
                    • Да, с помощью данного кода можно построить карту для записей.
                      Главное -- построить её один раз и далее ей пользоваться (обновляя при необходимости). Но не строить её каждый раз, когда нужно получить множество ссылок.
                      Ответить
                      • Дык мы спорим не о том, сколько раз этот код вызывать, а о том, почему бы при составлении карты записей не воспользоваться очевидной картой букв.
                        Ответить
                        • Когда я отвечал inkanus-gray, то я пояснил, что ускорение данного кода, который выполняет 26x<число_записей> операций, в 26 раз столь же очевидно, с точки зрения математики, сколь и ускорение в <число_записей> раз.

                          Естественно, что при составлении карты записей вполне прилично воспользоваться картой букв. Да.

                          UPD: когда у тебя 126 тыс. записей, то даже небольшие действия внутри одной из них, вообще-то, сложатся в макроскопическую величину, потому кажется мне, что логичнее ускоряться по записям, чем по буквам.
                          Ответить
                        • Меня ужаснула сама возможность того, что кто-то шерстит ТЫСЯЧИ, СОТНЮ ТЫСЯЧ записей в коде...
                          Это просто... Не поддаётся никакому осознанию...
                          Какие уж там 26 букв... Тут катастрофа просто...
                          Это вот так у меня в голове помутилось, когда я по ссылке прочитал.

                          UPD: Хотя я так и не понял, действительно ли там шерстят тысячи записей или их там выбирают по дополнительному условию. Если по доп. условию, то составление карты записей уже не есть возможно. Да и ускорение будет сравнимое с картой по буквам.
                          Ответить
                          • >Меня ужаснула сама возможность того, что кто-то шерстит ТЫСЯЧИ, СОТНЮ ТЫСЯЧ записей в коде

                            Вы это дайте компренде. Он это выполнит. Ему все непочем. Упоротый напроч. Притом не в коде, а вручную.
                            Ответить
                            • Ну вы видили, как он спокойно копипастит тонны бесполезных постов.
                              Ответить
                              • У меня нет даже слов, чтобы выразить моё отношение к этому субъекту.
                                :-(
                                Ответить
      • ...and after digging through the project, I isolated the problem. It was coming from an addressbook view; their addressbook had 120,000 entries, and displayed 50 at a time <...> in most cases this is just plain bad practice. But when checking 120,000 in the addressbook 26 times to generate a link list at the top of the addressbook view, it was definitely a bit wasteful
        Ответить
        • Так вот и выглядит всё это противоречиво: с одной стороны -- displayed 50 at a time (что можно понять как: в лист приходит 50 записей), с другой стороны -- checking 120,000 in the addressbook 26 times (это уже страшнее: из базы вынимают всё на прочёс для одной буквы).

          Боюсь, что в коде этого CMS могут содержаться ещё более ужасные вещи.
          Ответить
    • Make me unseen it!
      после вот этого
      $alphabet = split(' ', 'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z');
      наверно и не стоило дальше читать
      Ответить
    • Работает быстро:
      SELECT
        UPPER(LEFT(TRIM(FieldName), 1)) AS letter
      FROM
        TableName
      GROUP BY letter

      А потом уже выводить буквы. И не требуется ни какая доп.обработка кодом.
      Ответить
      • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
        Ответить
        • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
          Ответить
          • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
            Ответить
            • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
              Ответить
              • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
                Ответить
                • ГОРЯЧИЕ СУЧКИ ЖЕСТКИЙ АНАЛ ГОЛАЯ ЖАННА ФРИСКЕ БРИТНИ СОСЁТ ХУЙ ПЕРИС ХИЛТОН РАЗВРАТНАЯ ТВАРЬ ВЛАДИМИР ПУТИН ЕДЕТ В ИЗРАИЛЬ
                  Ответить
                  • Лечись и все пройдет. Впрочем единственное, что поможет - передозировка снотворным.
                    Ответить

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