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