2013-04-11 3 views
2

Я пишу программу, используя hadoop. мой вопрос код, как сильфонные (код в картографе):Почему BytesWritable.setSize (размер) делает пространство байтов равным 1,5 * размеру?

byte[] tmp = new byte[2]; 
tmp[0] = 0x01; 
tmp[1] = 0x02; 
BytesWritable outputKey = new BytesWritable(); 
outputKey.set(tmp, 0, 2); 

Однако, когда я действую ключ в редукторе, который я получил от картографа, он сделал мне сюрприз:

byte[] reducerKey = key.getBytes(); 

reducerKey как Belows:

reducerKey[0] -> 0x01; 
reducerKey[1] -> 0x02; 
reducerKey[2] -> 0x00; 

почему TMP, который я вход 2 байта длины, но когда я получил, он стал 3 байта длины.

Затем я прочитал исходный код BytesWritable.setSize (размер), я нашел это:

public void setSize(int size) { 
if (size > getCapacity()) { 
    setCapacity(size * 3/2); 
} 
this.size = size;} 

Так что, когда байты в в BytesWritable, почему структура данных создать 1,5 * размер пространства для байта []? Я думаю, что это пустая трата пространства, потому что пространство размером 0,5 * бесполезно.

ответ

1

Это распространенная практика программирования для амортизации стоимости dynamic array.

Теперь почему это не проблема и хорошее поведение по умолчанию для Hadoop-записей?

  1. Записываемые объекты, как правило, являются одноточиями, поскольку они могут быть и используются повторно. Вы обычно хотите их размер, чтобы соответствовать вашему самому большому буферу. Каждый раз создавая новый Writable, теряйте время и можете оказывать давление на GC. Имеет смысл сделать их немного больше, чем самый большой уже использованный буфер.
  2. Если вы хотите избежать дополнительной комнаты, вы можете использовать конструктор BytesWritable(byte[] bytes) или setCapacity. Обратите внимание, что конструктор намного эффективнее, чем set(), поскольку ему не нужно копировать данные. Необходимо установить только две ссылки.
Смежные вопросы