作者:承志68694849 | 来源:互联网 | 2023-05-17 08:05
你好,
我目前正在研究Java中的单词预测.为此,我使用的是基于NGram的模型,但我有一些内存问题......
在第一次,我有一个这样的模型:
public class NGram implements Serializable {
private static final long serialVersiOnUID= 1L;
private transient int count;
private int id;
private NGram next;
public NGram(int idP) {
this.id = idP;
}
}
但这需要大量的记忆,所以我认为我需要优化,我想,如果我有"向世界问好"和"向人民问好",而不是得到两个ngram,我可以保留一个"你好" "然后有两个可能性:"人"和"世界".
更清楚的是,这是我的新模型:
public class BNGram implements Serializable {
private static final long serialVersiOnUID= 1L;
private int id;
private HashMap next;
private int count = 1;
public BNGram(int idP) {
this.id = idP;
this.next = new HashMap();
}
}
但似乎我的第二个模型消耗了两倍的内存...我认为这是因为HashMap,但我不知道如何减少这个?我尝试使用不同的Map实现,比如Trove或其他,但它不会改变任何东西.
为了给你一个想法,对于一个9MB的文本,带有57818个不同的单词(不同,但不是单词的总数),在NGram生成之后,我的javaw进程消耗1.2GB的内存...如果我用GZIPOutputStream保存它,磁盘上需要大约18MB.
所以我的问题是:如何使用更少的内存?我可以用压缩制作东西(作为序列化).我需要将其添加到其他应用程序,所以我需要减少内存使用量之前......
非常感谢,抱歉我的英语不好......
ZiMath
1> Federico Per..:
你需要一个专门的结构来实现你想要的.
看看Apache的PatriciaTrie
.它就像一个Map
,但它是记忆方面的,并与String
s一起使用.这也是非常快:操作是O(k)
,与k
是最大的关键位的数量.
它有一个适合您眼前需要的操作:prefixMap()
它返回SortedMap
包含String
s 的trie视图,该视图以给定键为前缀.
一个简短的用法示例:
public class Patricia {
public static void main(String[] args) {
PatriciaTrie trie = new PatriciaTrie<>();
String world = "hello the world";
String people = "hello the people";
trie.put(world, null);
trie.put(people, null);
SortedMap map1 = trie.prefixMap("hello");
System.out.println(map1.keySet()); // [hello the people, hello the world]
SortedMap map2 = trie.prefixMap("hello the w");
System.out.println(map2.keySet()); // [hello the world]
SortedMap map3 = trie.prefixMap("hello the p");
System.out.println(map3.keySet()); // [hello the people]
}
}
还有测试,其中包含更多示例.