我需要在地图中存储价值对(单词和数字)。
我正在尝试使用来自Trove库的TObjectIntHashMap
并使用char[]
作为密钥,因为我需要最小化内存使用量。但是使用这种方法,当我使用get()
方法时,我无法获得该值
我想我不能使用原始字符数组存储在Map中,因为哈希码问题。
我尝试使用TCharArrayList
,但这也需要很多记忆
我在另一个与我的目的相似的stackoverflow问题中读到并建议使用TLongIntHashMap
,在长数据类型中存储String字的编码值。在这种情况下,我的单词可能包含拉丁字符或维基百科集合中出现的各种其他字符,我不知道Long是否足以进行编码。
我尝试使用Trie数据结构来存储它,但我也需要考虑我的性能,并选择最适合内存使用和性能。
您对此问题有任何想法或建议吗?
答案 0 :(得分:3)
听起来,存储数据最紧凑的方法是使用byte[]
中编码的UTF-8
或类似内容。您可以将它包装在您自己的类中,也可以编写自己的HashMap,它允许byte []作为键。
我会重新考虑花多少时间来节省一些记忆。如果您正在谈论PC或服务器,那么您需要以最低工资保存1 GB的工作时间,因此如果您只想节省100 MB,那么大约需要6分钟,包括测试。
答案 1 :(得分:0)
编写自己的实现CharSequence
的类,并编写自己的equals()
和hashcode()
实现。该实现还将预先分配大型共享char[]
存储,并一次使用它的位。 (你绝对可以将@Peter Lawrey的优秀建议纳入其中,并使用byte[]
存储。)
还有机会使用LRU缓存执行'soft intern()'。我已经注意到了缓存的位置。
这是我的意思的简单演示。请注意,如果您需要大量并发写入,可以尝试改进下面的锁定方案......
public final class CompactString implements CharSequence {
private final char[] _data;
private final int _offset;
private final int _length;
private final int _hashCode;
private static final Object _lock = new Object();
private static char[] _storage;
private static int _nextIndex;
private static final int LENGTH_THRESHOLD = 128;
private CompactString(char[] data, int offset, int length, int hashCode) {
_data = data; _offset = offset; _length = length; _hashCode = hashCode;
}
private static final CompactString EMPTY = new CompactString(new char[0], 0, 0, "".hashCode());
private static allocateStorage() {
synchronized (_lock) {
_storage = new char[1024];
_nextIndex = 0;
}
}
private static CompactString storeInShared(String value) {
synchronized (_lock) {
if (_nextIndex + value.length() > _storage.length) {
allocateStorage();
}
int start = _nextIndex;
// You would need to change this loop and length to do UTF encoding.
for (int i = 0; i < value.length(); ++i) {
_storage[_nextIndex++] = value.charAt(i);
}
return new CompactString(_storage, start, value.length(), value.hashCode());
}
}
static {
allocateStorage();
}
public static CompactString valueOf(String value) {
// You can implement a soft .intern-like solution here.
if (value == null) {
return null;
} else if (value.length() == 0) {
return EMPTY;
} else if (value.length() > LENGTH_THRESHOLD) {
// You would need to change .toCharArray() and length to do UTF encoding.
return new CompactString(value.toCharArray(), 0, value.length(), value.hashCode());
} else {
return storeInShared(value);
}
}
// left to reader: implement equals etc.
}