我在java中有一个很大的HashMap,存储从String到Integer的映射。它有400K记录。它运行正常,但我想知道在内存使用方面是否有更好的优化。初始化Map后,只会搜索它,不会进行其他更新操作。
我依稀记得我遇到过将字符串键转换为int的一些建议,但不确定。请帮助或分享您的想法。
感谢。
答案 0 :(得分:2)
我依稀记得我发现了一些将字符串键转换为int的建议,但不确定。
如果字符串键实际上是整数的字符串表示,那么使用Integer
将它们转换为Long
或Integer.valueOf(String)
个对象是有意义的。您将节省一些内存,因为原始包装类使用的内存少于相应的String
对象。节省空间可能很大(可能约为16个字节,而每个键约为40个字节......取决于您的平台。)
另一方面,在进行hashmap查找之前,您需要将候选键从String转换为实际键类型。这种转换需要一些时间,通常会产生一些垃圾。
但是如果String
键不表示整数,那么这根本不起作用。 (或者至少......我不知道你指的是什么“转换”......)
另请注意,密钥类型必须为Integer
/ Long
,而不是int
/ long
。通用类型参数必须是引用类型。
可能有第三方集合实现也有帮助......具体取决于您的数据结构的工作原理;例如Trove,Guava,Fastutil。尝试然后与String - >组合整数预转换...
关于使用数据库的建议。如果
然后使用数据库对每次查找都是一个很大的,不必要的性能影响。
答案 1 :(得分:1)
您可能希望调整initialCapacity
和loadFactor
以改善hashCode()
以避免发生冲突,如果您希望以更高的速率阅读,如果您有太多的写入,则可能需要进行基准测试{{ 1}},
即使这对你的应用程序来说太大了,你也可以考虑将它从jvm的一边移到某个缓存(redis),或者如果你能承受很小的读/写延迟,可能是数据库
答案 2 :(得分:1)
如果数据太大,将数据写入数据库最终是最佳解决方案,但400k仍然可以在内存中使用。
但是,Java的内置HashMap
实现使用单独的链接,并且每个键值对都有一个单独的类。通过构建Map
的二次探测实现,我获得了很大(30%)的速度提升和令人敬畏的(50%)内存改进。
我建议你在网上搜索一下。有很多很好的实现!
答案 3 :(得分:0)
您可以使用Guava's ImmutableMap
- 它针对一次性写入数据进行了优化,并采用~15% less memory than HashMap
。