Имеет ли смысл «тратить» 8 байтов на экземпляр String для смещения / подсчета? - PullRequest
4 голосов
/ 16 сентября 2011

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

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

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

E. г. имеет ли смысл иметь запечатанную, эффективную для памяти версию 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 Ответ

2 голосов
/ 16 сентября 2011

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

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

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

...