我正在用hadoop编写程序。我的问题代码如下(代码在mapper中):
byte[] tmp = new byte[2];
tmp[0] = 0x01;
tmp[1] = 0x02;
BytesWritable outputKey = new BytesWritable();
outputKey.set(tmp, 0, 2);
然而,当我操作从Map绘制器中得到的减速器钥匙时,它让我大吃一惊:
byte[] reducerKey = key.getBytes();
减速键如下:
reducerKey[0] -> 0x01;
reducerKey[1] -> 0x02;
reducerKey[2] -> 0x00;
为什么我输入的tmp是2字节的长度,但是当我得到时,它变成了3字节的长度。
然后我阅读了byteswritable.setsize(size)的源代码,我发现:
public void setSize(int size) {
if (size > getCapacity()) {
setCapacity(size * 3 / 2);
}
this.size = size;}
那么,当字节进入byteswritable时,为什么数据结构会为byte[]创建1.5大小的空间呢?我认为这是浪费空间,因为0.5大小的空间是没有用的。
1条答案
按热度按时间o4hqfura1#
这是分摊动态数组大小调整成本的常见编程实践。
为什么它不是hadoop可写文件的一个问题,也是一个好的默认行为呢?
可写对象通常是单例的,因为它们可以被重用。通常需要调整它们的大小以适合最大的缓冲区。每次创建一个新的可写文件,都会浪费时间,并且会给gc带来压力。使它们比已经使用的最大缓冲区大一点是有意义的。
如果想避免额外的空间,可以使用byteswritable(byte[]bytes)构造函数或setcapacity。请注意,构造函数比
set()
因为它不必复制数据。只需设置两个引用。