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

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
byte[] buf = new byte[8192];
int len = 0;
while ((len = is.read(buf))>0)
{
    requestString += new String(buf, 0, len, "UTF-8");
}

Пока никто не кормил туда настоящий UTF-8. Только ascii.

Запостил: konsoletyper konsoletyper, (Updated )

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

    • Лучше уж тогда BufferedReader. А вообще, вариантов куча. Например, IOUtils из apache commons (тем более, что оный обнаружен в classpath'е проекта) или какой-нибудь nio
      Ответить
  • Проблема возникнет, если символ придется на край буфера?
    Ответить
      • Эх... Вот если бы он еще сам по байтикам разбирал, типа if ((b1 & 0x80) != 0) { b2 = is.readByte(); ... }
        Ответить
          • Хотя не все.

            Он бы всяко забыл про то, что следует игнорить символы, записанные не самым кратким образом. Например если 0x0A записали в виде двух-трех байт.
            Ответить
    • А ещё тормоза из-за постоянного перевыделения памяти при конкатенации строк
      Ответить
      • А как делают мастера, если надо собрать n строк в одну?
        Ответить
            • Ну на низком уровне - сложить все строки во что-то типа стека (лишь бы вставляло за О(1)) и затем за один concat поклеить их.
              Ответить
            • Если бы у меня было большое желание написать string-builder на сишке, я бы поступил так:
              завёл структуру
              typedef struct {
                  char *data;
                  size_t capacity;
                  size_t tail;
              } string_builder_t;

              ввёл бы несколько функций
              string_builder_t* new_builder(size_t);
              string_builder_t* append_to(string_builder_t*, char *, size_t);
              char *to_string(string_builder_t*);
              append_to() работает очень просто: складывает символы в массив, обновляя значение tail. Когда кончается место (tail + len> capacity) - реаллочит массив, увеличивая размер в полтора-два раза.
              Ответить
              • Плюсую, в проекте на С использовал именно такой буфер.
                Только в интерфейсе модуля были еще buffer_free и buffer_size.

                P.S. А тот вариант который я писал выше (про стек) он для языков с GC (в частности в Lua так реализована склейка строк).
                Ответить
                  • На что только не пойдут плюсовики, лишь бы не использовать GObject.

                    (Кстати, о GObject: в GLib есть GString, который в Vala замаплен под именем - да-да, StringBuilder. И реализован он именно так.)
                    Ответить
                    • судя по минусам, мой безобидный вброс таки доставил батхёрта
                      кстати о именно так - именно так реализовано много чего, от std::vector до, ты не поверишь, std::string, обычно лежащего в основе да-да, std::stringbuf
                      и не удивлюсь, если эта незатейливая идея, которую С предлагает изобрести ручками каждый раз заново, именно так реализована в библиотеках еще кучи языков
                      Ответить
              • >увеличивая размер в полтора-два раза
                Любопытно, кстати, в Qt реализовано: поначалу выделяются степени двойки (минус константа), а при достижении размера около 4080 байт рост дальше идет линейно, размер увеличивается шагами в 4096 байт. Объясняется это тем, что при realloc-е система просто перемапливает старые страницы, а не копирует байты, поэтому наращивание массива происходит очень быстро.
                Ответить
                • Но это только при условии, что вектор действительно делает realloc, а не создание нового куска и копирование.
                  Кстати, как realloc подружить с конструктором сдвига?
                  Ответить
                    • Из corelib/tools/qvector.h:
                      template <typename T>
                      void QVector<T>::append(const T &t)
                      {
                          if (d->ref != 1 || d->size + 1 > d->alloc) {
                              const T copy(t);
                              realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T),
                                                                 QTypeInfo<T>::isStatic));
                              if (QTypeInfo<T>::isComplex)
                                  new (p->array + d->size) T(copy);
                              else
                                  p->array[d->size] = copy;
                          } else {
                              if (QTypeInfo<T>::isComplex)
                                  new (p->array + d->size) T(t);
                              else
                                  p->array[d->size] = t;
                          }
                          ++d->size;
                      }


                      POD'ы быстро и грязно, а классы как положено.
                      Ответить
                      • Тьфу, не ту функцию кинул. Надо было QVector::realloc(). Но суть та же самая - через тайпинфо проверяется POD ли это, и если да - используется чит.
                        Ответить
                        • фу
                          1) это должно быть через специализации сделано, а не отдано на откуп компиляторной оптимизации if (0) stmt1; else stmt2; --> stmt2;
                          2) размер в байтах на сколько надо вырасти известен аллокатору, не нужно подсовывать никаких sizeOfTypedData() и sizeof(T)
                          как всегда Qt блещет вылизанностью, не то, что мерзкий стандарт для лохов, ага
                          Ответить
                          • >это должно быть через специализации сделано
                            Т.е. вы предлагаете растащить специализации, сосредоточенные в QTypeInfo, по всем подряд контейнерам?
                            Ответить
                            • ничего сверхъестественного там не сосредоточено, разница POD-неPOD очевидно хранится в значении QTypeInfo<T>::isComplex = true|false, известном на этапе компиляции, посему не вижу проблем сделать шаблон от bool, делающий неPOD функционал и рядом специализацию от <true>, делающую POD функционал

                              в голову приходит лишь объяснение, что Qt мол собралась компилироваться компилятором вообще без поддержки partial specialization

                              <наброс>а взрослую библиотеку информации по типам можно посмотреть вот тут http://bit.ly/Jyomed </наброс>
                              Ответить
                              • > посему не вижу проблем сделать шаблон от bool
                                Согласен
                                Ответить
                              • >Qt мол собралась компилироваться компилятором вообще без поддержки partial specialization

                                Точно, некоторые фичи в Qt не используются, потому что не поддерживаются всеми компиляторами.
                                Ответить
                    • Можно ли на уровне операционки сделать так, чтобы менеджер памяти поддерживал неподы?
                      Ответить
                      • на уровне операционки... ей все равно, она отдала очередную страницу процессу и следит, чтобы тот не влез в несуществующую

                        если что и ковырять - так это менеджер кучи, т.е. либо идти в обход того, который реализован в рантайме, либо надстраиваться поверх malloc

                        что должен делать такой менеджер кучи? на каждый чих сохранять адрес копирующего конструктора для каждого выделяемого пойнтера, либо признак что конструктора нет (== plain old data, достаточно побитового копирования)

                        что такое кастомный менеджер кучи в понятии С++ - в первом приближении - свой аллокатор, но типичное для stl stateless использование аллокатора печалит и отторгает
                        тем не менее, myalloc<T>::construct(ptr, T &) и myalloc<T>::destroy(ptr, count) предоставляют понимание какой конкретно тип создается по конкретному указателю, так что можно составлять таблицу типов, привязывать пойнтер к записи в таблице, там искать указатель на копирующий конструктор. как-то так

                        можно избавить контейнер от не очень то сложных действий in place, зато очень сильно усложнить кастомный менеджер кучи, + наверняка вся эта конструкция будет работать еще и медленнее
                        выхлоп не тот, всего то ради выбора memcpy/copy(dest, first, last)

                        вот если в менеджер еще запихать функциональность сборщика мусора и кофеварки, тогда можно и за валидным копированием элементов следить, да
                        Ответить
  • Надо ещё чтобы файл был немаленький и разрыв codepoint происходил на байте, кратном 8192.
    Ответить

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

Из-за тебя ушел bormand, guest!

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


    8