2015-04-12 120 views
1

我创建了一个trie,我的应用程序将其保存在内存中。 Trie将有很多节点,我正在考虑如何减少空间使用量。 因为我将使用trie到DAWG算法来减少节点的数量,但据我所知这还不够。Java减小对象的大小

这里是一个节点类

class Node{ 
    char letter; 
    boolean EOW; // end of word 
    Node child; // first child 
    Node next; // next Node on this level 
} 

据我知道这个类的对象将具有14个字节(2个字节用于炭,4为布尔变量和2 * 4将被保留用于参考给定的)

我认为我可以用字节替换char。这将节省1字节。但是我不知道类型转换需要多少时间。可能这是一个糟糕的设计。

此外布尔值需要4个字节,也许你知道我可以使用,而不是布尔值?

所以我需要你帮我减小节点的大小。提前致谢。

+0

您能否以面向对象的方式实现它,因此您有'EndOfWordNode extends Node',隐式指示布尔值? –

+0

@AndyTurner尝试的方式通常是构建的,这可能会让事情变得更加困难。 – immibis

+0

@immibis“更难”确定。我宁愿不这样做。但是,如果空间是首要考虑的因素,那么可能要吃困难就是价格。 –

回答

1

如果你不需要的UTF-16字符的怪异一半,你可以使用letter最高位为EOW标记。

例如,这里的eoWletterA变量的字母“A”编码与EOW位:

char eoWletterA = 'a' + 0x8000; 
char letter = (char) (eoWletterA & 0x7FFF); 
boolean eow = BigInteger.valueOf(eoWletterA).testBit(15); 

您的线索应适当封装。将字符存储到trie时,确保EOW位不能被意外设置。

更新:请注意,从节点中删除boolean变量可能会或可能不会影响JVM中Node对象的内存占用量。您可以使用以下工具检查对象内存占用空间:https://stackoverflow.com/a/52682/1207523

+0

我会检查它) –

+0

相当不错的代码) –

+0

谢谢:)当然,它可以优化,可读性权衡,如果你有高性能要求。 – Mikuz

2

如果letter只需要5位和eow一位,那么可以将它们打包在一个单独的byte中以节省内存。

char letter = ...; 
boolean eow = ...; 

byte packed = (byte) ((eow ? 0b10_0000 : 0) | letter); 

letter = (char) (packed & 0b1_1111); 
eow = (packed & 0b10_0000) != 0; 
+0

哇,男人,我需要一些时间来了解这个代码)谢谢,我会检查它 –