Занимает ли Map.empty и None одинаковое количество памяти?

#scala

Вопрос:

Если у меня есть класс case, который выглядит так:

 case class User(id: String, settings: Map[String, String])
 

Будет ли разница с точки зрения объема памяти при создании экземпляра этого объекта, если я определил его следующим образом:

 case class User(id: String, settings: Map[String, String] = Map.empty[String, String])
 

против

 case class User(id: String, settings: Option[Map[String, String]] = None)
 

Таким образом, мы сравниваем свойство классов обращений, являющееся либо пустой картой, либо значением » Нет » для типа опции.

Есть ли разница с точки зрения объема памяти в экземплярах User ?

Комментарии:

1. Обратите внимание, что это Option[Map] означает, что данные могут быть пустыми двумя способами, это может быть желательно, но в большинстве случаев лучше использовать Option[NonEmptyMap]

Ответ №1:

Оба None и Map.empty objects без полей, поэтому будут иметь одинаковое потребление памяти (в типичной JVM около 20 байт-это правильный порядок величины).

Обратите внимание, что моделирование в качестве Option[Map] накладных расходов (на типичной JVM, что-то вроде 30 байт) для каждого непустого случая. Таким образом, при использовании вместо пустого нет экономии памяти None Map .

Единственная веская причина, по крайней мере, по моему опыту, когда-либо использовать an Option[Map] в сочетании с такими вещами, как сериализация на основе макросов, когда вы моделируете, что на карте может даже не быть поля в сериализованном представлении.

Ответ №2:

None является ан object . Таким образом, он уже создан для вас и используется повторно каждой ссылкой.

Теперь вопрос в том, что Map это такое ? mutable или immutable ?

immutable.Map.empty[A, B] похоже None на это таким образом. Просто у него больше полей и он «на самом деле» займет больше памяти, но эта разница будет Bytes и может быть проигнорирована.

В то mutable.Map.empty[A, B]() время как каждый раз будет создаваться новый пустой объект карты, вы создадите любой его экземпляр User . Таким образом, None это приведет к меньшему объему памяти по сравнению с mutable.Map.empty[A, B]() .

Комментарии:

1. AFAICT, по крайней мере, по состоянию на 2.13.6, просматривая исходный код , я не вижу в нем никаких полей scala.collection.immutable.Map.EmptyMap , что Map.empty и возвращает.

2. Я не говорил о членах класса, имеющих значение. Map имеет два параметра типа, которые будут «представлены» class экземплярами во время выполнения. Я говорил об этих «полях».

3. AFAIK, JVM не хранит экземпляры классов связанных типов, у вас есть для этого ссылка? (и при проверке байт-кода не происходит внедрения экземпляров классов, созданных компилятором)