Есть ли какое-то избирательное преимущество в кешировании строки вместо объекта в Java? Отличается ли Python? - PullRequest
0 голосов
/ 09 мая 2020

Один мой дорогой коллега однажды предложил мне, что предпочтительнее сериализовать объекты (например, карты, JsonObjects и c.) В строки и хранить их в кешах вместо самих объектов для менее активных кешей. Причина, по которой он указал, заключалась в том, что, поскольку все эти объекты имеют свои собственные методы и еще много чего, это увеличивает площадь объекта. Я понимаю, что строки тоже имеют свои собственные методы, но не огромные. Он предположил, что это все же предпочтительный выбор, даже с учетом дополнительных затрат на синтаксический анализ строк и их преобразование обратно в исходные объекты во время извлечения.

Есть ли вода в этих утверждениях? Или есть еще какие-нибудь предложения по этому поводу?

1 Ответ

0 голосов
/ 09 мая 2020

Методы и тому подобные загружаются один раз для каждого класса. Они не занимают дополнительной памяти независимо от того, сколько экземпляров класса вы создаете.

В Java размер следующего объекта составляет 16 байтов:

class EmptyObject {
}

Если ваш объект содержит ссылки, каждая ссылка составляет еще 8 байтов. Так, например, размер следующего объекта составляет 80 байтов:

  • 16 байтов для определения экземпляра
  • 8 байтов для ссылки на массив
  • 16 байтов в фактический массив
class AnotherObject {
  byte[] bytes = new byte[16];
}

Теперь предположим, что мы кэшируем наши объекты, и предположим, что кеш - это прославленный HashMap, поскольку он по существу хранит пару ключ-значение.

Рассмотрим следующий класс. Для пустых строк требуется 32 байта:

class Person {
  String firstName;
  String lastName;
}

Допустим, ваши ключи - это строки длиной 16 байтов; 32-байтовые объекты.

Если вы поместите Person в кеш, для ссылки на ключ потребуется

  • 8 байтов
  • 32 байта для ключа
  • 8 байтов для ссылки на значение
  • 32 байта для значения

Всего: 80 байтов

Теперь предположим, что мы храним строки по отдельности . Для каждого ключа:

  • 8 байтов для ссылки на ключ
  • 32 байта для ключа
  • 8 байтов для ссылки на значение
  • 16 байтов для значения ( пустая строка)

Умножить x2. Всего: 128 байт


Только в этом случае имеет смысл хранить строки вместо объектов:

class StringWrapper
  // the only field in the class
  String string;
}

, но даже тогда экономия номинальный.

TL; DR: это микрооптимизация, которая в большинстве случаев не стоит того

...