Имеет ли смысл "тратить" 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
делает.