为什么BytesWritable.setSize(size)将字节空间设置为1.5 * size?

问题描述:

我正在使用hadoop编写程序。我的问题的代码是初级讲座(代码是在映射器):为什么BytesWritable.setSize(size)将字节空间设置为1.5 * size?

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是作为初级讲座:

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 *大小的空间是无用的。

这是一个常见的编程实践,以摊销dynamic array调整大小的成本。

现在为什么它不是Hadoop可写入的问题,并且是一个很好的默认行为?

  1. 可写入的对象通常是单例,因为它们可以被重用。您通常需要调整它们以适合您的最大缓冲区。每次创建一个新的Writable,浪费时间并且可能对GC施加压力。使它们比最大的已经使用的缓冲区大一些是有意义的。
  2. 如果你想避免额外的空间,你可以使用BytesWritable(byte[] bytes)构造函数或setCapacity。请注意,构造函数比set()更有效,因为它不需要复制数据。只需要设置两个参考。