1. Java / Говнокод #3280

    +80

    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
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    private String nextUTF8Character() throws IOException, CharacterCodingException
      {
        int iCodePoint = 0;
        int byte1, byte2, byte3, byte4;
        byte1 = is.read();
        if (byte1 == -1)
          return null;
        // проверяем является ли первый бит нулевым
        if ((byte1 & 0x80) == 0)
        {
          // один байт
          iCodePoint = byte1 & 0x7F;
          return new String(Character.toChars(iCodePoint));
        }
        byte2 = is.read();
        if (byte2 == -1)
          return null;
        if ((byte1 & 0xE0) == 0xC0 && (byte2 & 0xC0) == 0x80)
        {
          // два байта
          iCodePoint = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);
          if (iCodePoint > 0x7F)
            return new String(Character.toChars(iCodePoint));
          else
            throw new CharacterCodingException();
        }
        byte3 = is.read();
        if (byte3 == -1)
          return null;
        if ((byte1 & 0xF0) == 0xE0 && (byte2 & 0xC0) == 0x80 && (byte3 & 0xC0) == 0x80)
        {
          // три байта
          iCodePoint = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
          if (iCodePoint > 0x7FF)
            return new String(Character.toChars(iCodePoint));
          else
            throw new CharacterCodingException();
        }
        byte4 = is.read();
        if (byte4 == -1)
          return null;
        if ((byte1 & 0xF8) == 0xF0 && (byte2 & 0xC0) == 0x80 &&
                (byte3 & 0xC0) == 0x80 && (byte4 & 0xC0) == 0x80)
        {
          // четыре байта
          iCodePoint = ((byte1 & 0x07) << 18) | ((byte2 & 0x3F) << 12) |
                  ((byte3 & 0x3F) << 6) | (byte4 & 0x3F);
          if (iCodePoint > 0x0FFFF)
            return new String(Character.toChars(iCodePoint));
          else
            throw new CharacterCodingException();
        }
        throw new CharacterCodingException();
      }

    Мегаоптимизированный код для получения букафф в кодироффке UTFфф-8
    По данным профилировщика именно этот фрагмент самый тормозной в моей сетевой проге

    Запостил: Max ID, 20 Мая 2010

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

    • Причем, я подозреваю, самое тормозное место в самом тормозном фрагменте - это new String().
      Ответить
      • блин такое даже в С/С++ будет подтормаживать.

        но меня больше порадовал тот факт что оно посимвольно читает из потока - и посимвольно делает "new String(Character.toChars(iCodePoint));"

        не верю что в Жабе нет какого штатного конвертора utf-8 <-> ucs2.
        Ответить
        • Ну да, о чем я и говорю.
          http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html
          Ответить
          • К моему БОЛЬШОМУ сожалению, я не мог использовать чарсет (я его только для енкодера использую), т.к. этот говнокод делался для кастомного XML-анализатора, который мог включать бинарные данные. Следовательно, тут надо анализировать посимвольно, чтобы дойти до того места, где начинаюццо бинарные данные. Я и так уже сначала считывал в байтовый буфер (ByteArrayInputStream, кажеццо), так что хотя бы не с потока.
            А вообще у меня было бы так:
            vbttemp = new byte[len];
            is.read(vbttemp);
            Charset cs = Charset.forName("UTF-8");
            String s = cs.decode(ByteBuffer.wrap(vbttemp)).toSt ring();
            Ответить
            • > XML-анализатора, который мог включать бинарные данные

              *без комментариев*

              это уже не говно-код - это говно-днк.
              Ответить
              • Ну, найди мне пример готового, умник!
                Может, еще предложишь использовать Base64 ? Или, может, BinaryXML, как в матрешке?
                Ответить
                • так а что ты здесь гового то нашел? если тебе UTF-8 парсер руками писать пришлось????

                  XML по определению для структурированых данных.

                  И смысла в XML все пихать нет, если XML перестает быть совместимым со всеми остальным (тот же XSLT к примеру).

                  Если нужны блобы, сливай их в отдельный файл а в XML только делай на них ссылку. И парсить руками не надо, и лишний раз ничего конвертировать не надо.

                  N.B. Блин, даже SQL сервера блобы отдельно держать - потому что неструктурированые данные есть evil, даже если и "necessary evil".

                  Ну или в крайнем случае - да, какой Base64. Или чего угодно что быстро конвертиться и не портит XML.
                  Ответить
                  • Ну, мне действительно нужны блобы.
                    Вся это шняга передаеццо по сети, и мне каждый байт дорог :)
                    Что уже говорить про конвертации бинари - текст, где на треть увеличивается длина блоба. Конечно, можно использовать алгоритм хаффмана, у меня даже есть где-то его говнокодная реализация :)
                    Ответить
                    • Какие к чертям собачьим хаффман и кастомные xml парсеры.

                      Блобы отделяются от XML, потом все складывается в самопальный контейнер (не имеющий никакого отношения к XML, если хочется универсальности можно покурить rfc2387 для вдохновения), который уже и проходит через сеть.
                      Ответить
                      • А где здесь написано, что это НАСТОЯЩИЙ XML?
                        Это и есть самопальный контейнер!
                        Ответить
                        • Вот здесь http://govnokod.ru/3280#comment27097
                          >> этот говнокод делался для кастомного XML-анализатора

                          Я к тому что зачем использовать для передачи данных изнасилованный-XML-с-блобами (и плодить говно-анализаторы), когда можно сделать простейший контейнер (который на порядки проще XML) и уже в него вкладывать блобы (как они есть) и настоящий XML.
                          Ответить
                          • Ну куда уже проще -
                            <data bin длина_данных>
                            пошел_массив_байтов
                            </data>
                            Это даже чем-то похоже на bencode
                            Ответить
                            • Куда угодно. Сохранять данные отдельным фаилами и tar'ить их вместе с xml'ом и то проще.

                              Это решение - полное говно: оно подразумевает создание собственного варианта XML, причем отличающегося на самом базовом уровне.

                              И все для задачи, элементарно решаемой оберткой НАД xml'ом
                              Ответить
                    • блин он о байтах заботиться.... еще и хафмана приплетает.

                      с таким кодом, с такой производительностью, тебе наверное 32+ ядер/потоков понадобится что бы гигабит эзернет канал забить.

                      сделай по тупому - сконвертни все в текст - и проверь насколько канал заполнен. мне слабо верится что ты и до половины ширины гигабитного канала доходишь.
                      Ответить
                      • Ха, говорю НЕ о скорости передачи данных, а об объеме
                        Ответить
                    • Если нужны блобы и дороги байты - сделай бинарный протокол.
                      Но вот это "каждый байт дорог", как правило, бывает преувеличено.
                      Ответить
        • >блин такое даже в С/С++ будет подтормаживать.
          Тут не язык нужно менять, а алгоритм нормальный написать, а лучше вообще использовать старые проверенные средства.
          Ответить
      • Если его убрать, то почему-то не работает :)
        Ответить
        • Ты бы не умничал, а подумал бы чем заменить :)
          Блин, у тебя НА КАЖДОМ символе выделяется память в куче. + отрабатывает тяжеленный конструктор.
          Ответить
          • Дак я ж только ЗА обеими руками. Но как его заменить? Можно, конечно, кодовые точки возвращать... А как потом сделать проверку типо:
            if ("<".equals(кодовая_точка))
            ...
            Хотя, возможно, если как-то переконвертить "<" в кодовую точку, например Character.toCodePoint(char high, char low), а потом сравнить...
            Ответить
            • Для начала, нафига ты вообще строку создаешь?
              Ответить
              • Слушай, а ты монстрюга! Действительно, нах я ее создаю...
                Там же дальше у меня в коде идет метод типа charAt(0).

                P.S. А шо ты хатев? Ето ш гамнокодъ!
                Ответить
                • Далее. Откуда у тебя в xml бинарные данные? Какой это тогда вообще xml? %)
                  Все бинарные данные в xml должны быть в BASE32/64 или чем-нибудь таком.
                  Тогда ты сможешь пользоваться Charset.

                  Ну и на сладкое - строить строку в твоем случае надо StringBuilder'ом. А не string new = old + nextUTF8Character();
                  Ответить
              • Чувак, на говнокоде должно лежать говно. Не спрашивай: "Почему автор сговнокодничал?". Ты так говоришь, будто он не исправился и продолжает это говно использовать.
                Говнокод - это как поход к психологу. Если человек рассказал о своём говне, то ему станет легче. Не нужно его за это укорять или искать причину, а то вследующий раз не придёт причастится на говнокод и будет тихо говнякать.
                Ответить
                • Судя по его ответам, он ступил и готов исправиться.
                  Че бы не помочь человеку?
                  Может говнокода меньше станет :)
                  Ответить
    • Я скоро выложу крутой интерпретатор арифметических выражений, который я делал в девятом классе. Ручаюсь, ТАКОГО говнокода говнокод.ру не видел
      Ответить
    • Я стал ласкать их. У них, был свой вкус. Не такой, как у Наташкиных, и не такой, как у других женщин, а особый, только ей принадлежащий, волшебный вкус.
      Ответить

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