1

我需要在地图中存储值对(单词和数字)。

我正在尝试使用TObjectIntHashMapTrove 库char[]中的密钥,因为我需要尽量减少内存使用量。但是使用这种方法,我在使用get()方法时无法获取值。
我想我不能使用原始字符数组来存储在 Map 因为哈希码问题。

我尝试使用TCharArrayList,但这也需要很多内存。
我阅读了另一个与我的目的相似的stackoverflow问题,并建议使用TLongIntHashMap,将字符串字的编码值存储为长数据类型。在这种情况下,我的单词可能包含拉丁字符或维基百科集合中出现的各种其他字符,我不知道 Long 是否足以进行编码。

我曾尝试使用 Trie 数据结构来存储它,但我还需要考虑我的性能,并为内存使用和性能选择最佳的。

您对这个问题有什么想法或建议吗?

4

2 回答 2

3

听起来最紧凑的数据存储方式是使用byte[]编码的UTF-8或类似的。您可以将其包装在您自己的类中或编写您自己的 HashMap ,它允许 byte[] 作为键。

我会重新考虑花费多少时间来节省一些内存。如果您谈论的是 PC 或服务器,以最低工资计算,您需要为一个小时的工作节省 1 GB,所以如果您只想节省 100 MB,包括测试在内大约需要 6 分钟。

于 2012-10-24T17:32:09.200 回答
0

编写您自己的实现 的类CharSequence,并编写您自己的equals()和实现hashcode()。该实现还将预先分配大型共享char[]存储,并一次使用它的一部分。(您绝对可以将@Peter Lawrey 的出色建议也纳入其中,并使用byte[]存储。)

还有机会使用 LRU 缓存执行“软实习生()”。我已经注意到缓存的去向。

这是我的意思的简单演示。请注意,如果您需要大量并发写入,您可以尝试改进下面的锁定方案...

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.
}
于 2012-10-24T18:00:09.070 回答