Подтвердить что ты не робот

Scala накладные расходы на память кортежа

Что такое дополнительная стоимость памяти Tuple [Int, Int], т.е. (1, 2) над двумя Ints без Tuple?

4b9b3361

Ответ 1

Накладные расходы JVM обычно составляют от 16 до 24 байтов на объект (соответственно 32-разрядные и 64-разрядные, хотя сжатые указатели могут уменьшить последнее). Tuple2 специализируется на Int, что означает, что он сохраняет значения в полях, поэтому у вас есть 8 байтов для двух ints по сравнению с 8 + 16 = 24 или 8 + 24 = 32 для (1,2). Если вы используете аналогичную неспециализированную коллекцию (или используете Tuple2 для чего-то, что не специализируется, например Char), вам нужны указатели на объекты, и вам могут понадобиться объекты в зависимости от того, могут ли они быть предварительно выделены (произвольные целые числа, нет, произвольные байты, да, произвольные символы, возможно). Если да, то вам нужен только указатель, а он 8 + 16 = 24 или 16 + 24 = 40 байт; если нет, вам нужны три объекта, поэтому это 16 + 8 + 2 * (16 + 4) = 64 и 24 + 16 + 2 * (24 + 4) = 96 соответственно.

Нижняя строка: объекты используют намного больше памяти, чем примитивные типы, обычно 3-4x, но иногда более 10x. Если у вас мало памяти, упакуйте столько, сколько вы можете в массивы. Например:

Плохо для использования памяти:

val a = (1 to 10000).map(x => (x,x.toString.length)).toArray

Хорошо использовать память:

val b = ((1 to 10000).toArray, (1 to 10000).map(_.toString.length).toArray)

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