Имеет ли смысл "тратить" 8 байтов на экземпляр String для смещения / подсчета?

Строки в Java поддерживают структурное совместное использование для некоторых методов, таких как substringЭто означает, что предположительно неизменяемые данные не нужно копировать (что (неожиданно) поддерживает большие массивы символов, которые в противном случае были бы GC).

Эта функция реализована с двумя полями offset а также count которые установлены соответственно, когда строка substringредактировать на Java.

Учитывая, что .NET этого не делает и утверждает, что "O(n) - это O(1), если n не становится большим", будет ли иметь смысл несколько иной дизайн строк, который учитывает оба требования?

Например было бы целесообразно иметь запечатанную, эффективную для памяти версию String общего назначения, которая не имеет этих лишних полей, и подкласс "SubString", который возвращается только substring методы и есть дополнительные поля, чтобы избежать копирования?

Набросок:

sealed class String {
  val codeunits: Array[Char] = ...
  def length = codeunits.length

  def substring: SubString = ...

  ...
}

final class SubString extends String {
  val offset: Int = ...
  override def length = codeunits.length - offset /* and so on */

  ...
}

1 ответ

Решение

То, что вы предлагаете, может сделать общий случай более эффективным с точки зрения памяти и процессора.

Вам может быть интересно знать, что JVM может изменить это без изменения кода. В настоящее время Sun/Oracle JVM автоматически использует byte[], когда символы помещаются в байты без потерь.

В любом случае это то, что вы хотели бы, чтобы JVM сделала для вас прозрачно, например -XX:+UseCompressedStrings делает.

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