Jawa / Говнокод #3280 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 Max ID, (Updated )

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

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

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

      не верю что в Жабе нет какого штатного конвертора utf-8 <-> ucs2.
      Ответить
        • К моему БОЛЬШОМУ сожалению, я не мог использовать чарсет (я его только для енкодера использую), т.к. этот говнокод делался для кастомного 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();
                Ответить
            • Чувак, на говнокоде должно лежать говно. Не спрашивай: "Почему автор сговнокодничал?". Ты так говоришь, будто он не исправился и продолжает это говно использовать.
              Говнокод - это как поход к психологу. Если человек рассказал о своём говне, то ему станет легче. Не нужно его за это укорять или искать причину, а то вследующий раз не придёт причастится на говнокод и будет тихо говнякать.
              Ответить
              • Судя по его ответам, он ступил и готов исправиться.
                Че бы не помочь человеку?
                Может говнокода меньше станет 🙂
                Ответить
  • Я скоро выложу крутой интерпретатор арифметических выражений, который я делал в девятом классе. Ручаюсь, ТАКОГО говнокода говнокод.ру не видел
    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8