Как эффективно сериализовать String в существующий ByteBuffer?

Кажется, что String.getBytes() создаст новый байтовый массив, так что будет дополнительная копия памяти. Могу ли я закодировать строку прямо в ByteBuffer без промежуточного байтового массива?

например:

void putString(ByteBuffer bb, String s) {
    byte[] arr = s.getBytes(StandardCharsets.UTF_8);
    bb.put(arr);
}

Этот фрагмент кода создаст байтовый массив, закодирует строку в этот байтовый массив, а затем скопирует содержимое байтового массива в ByteBuffer. Я думаю, что массив байтов не нужен, он принесет GC и дополнительную копию памяти.

4 ответа

Решение

Ты можешь использовать CharsetEncoder написать прямо в ByteBuffer:

static void putString(ByteBuffer buffer, String str, Charset charset) {
    CharsetEncoder encoder = charset.newEncoder();
    encoder.encode(CharBuffer.wrap(str), buffer, true);
    encoder.flush(buffer);
}

Это ваша ответственность, чтобы убедиться, что достаточно места было выделено. Вы также можете проверить результат encode() метод, чтобы увидеть, если это было успешно.

Я не могу придумать простой способ полностью исключить промежуточные байтовые массивы.

Однако, если вы беспокоитесь об этом, потому что строка огромна, вы можете разбить ее на куски:

  for(offset=0; offset<str.length(); offset+=chunkSize) {
      String chunk = str.substring(offset, offset+chunkSize);
      byteBuffer.put(chunk.getBytes(StandardCharsets.UTF_8));
  }

Однако, если ваши входные строки достаточно велики, чтобы эта оптимизация была необходима, общая архитектура вашей программы, вероятно, неверна.

Вам не следует беспокоиться о производительности GC, если вы не увидели чего-то необычного во время профилирования. JRE великолепен в эффективном GC.

Нет, это невозможно. Строковые объекты не имеют кодировки.

Строковые объекты неизменны по назначению. Вся идея этого класса состоит в том, чтобы не позволять манипулировать какими-либо базовыми структурами данных (в основном по соображениям безопасности и оптимизации производительности).

В этом смысле: нет другого лучшего подхода для получения байтов, составляющих строковый объект в Java.

Другие вопросы по тегам