Java - 链接到同一对象值的两个哈希映射键?

问题描述 投票:0回答:1

我想通过两种方式访问对象...

一个是通过 UUID。

一种是通过显示名称。

我目前将这些映射存储在内存中,因为我想最大限度地减少 CPU 的工作量。

实现此目的的一种方法是循环遍历所有装饰对象并匹配显示名称以返回相应的装饰对象。然而,这些操作每秒可能运行多次,因此会对 CPU 造成太大压力。

所以,我目前的设置是这样的:

    private Map<String, Cosmetic> cosmeticIDs;
    private Map<String, WeakReference<Cosmetic>> cosmeticsDisplayNames;
    Cosmetic cosmetic = new Cosmetic(UUID, displayName);
    cosmeticIDs.put(cosmetic.getID(), cosmetic);
    cosmeticsDisplayNames.put(cosmetic.getDisplayName(), new WeakReference<>(cosmeticIDs.get(cosmetic.getID())));

这些地图在应用程序启动时加载,并且永远不会改变。

有更好的方法吗?看来我目前浪费了很多内存。

java hashmap key
1个回答
0
投票

您的 WeakReference 在这里绝对没有任何作用。您弱引用的对象由

cosmeticIDs
哈希图强保留,因此无法被收集,使得 WeakReference 在这里毫无用处。只需将第二张地图设为
Map<String, Cosmetic>
即可。

看来我目前浪费了很多内存。

所有非原语在java中都是引用。

Cosmetic
本身就是已经是一个参考。映射的第二个映射引用字符串(因此,64 位指针可能取决于许多因素;CPU、JVM 的位数、是否启用 CompressedOOPS 等等,但假设是 64 位),对化妆品的引用,因此,另一个 64 位值。

假设您有 10,000 种化妆品 - 这些东西由于某种原因已经在内存中(例如:因为

cosmeticIDs
存在)。

因此,

cosmeticsDisplayNames

映射或多或少需要 10,000 * (64 + 64) 位内存(比这个多一点,当然,哈希映射需要一些空间来进行自己的簿记)。所以,160,000 字节,或 160k。例如,您的平均系统具有 8GB RAM,这意味着它占总 RAM 的 0.001907%。

看来我目前浪费了很多内存。

那么,那就是“不”。

但是,这些操作每秒可能运行多次,因此会对 CPU 造成太大压力。

你给人的印象是一个毫无头绪但非常担心表现的人。您正在从“对 CPU 压力的担忧”和“对浪费内存的担忧”中跳来跳去。

停止这样做。计算机的速度非常快,正如你所看到的,这些东西的成本不到万分之一。如果您每秒查找化妆品数百万次,就会“给您的 CPU 带来压力”。如果您这样做,那么,是的,您的计算机正在提供一个可供数千人同时访问的网站,它正在完成其工作。

担心性能对于编程来说是毁灭性的。你可能会因为试图“找到最高效的方式”而陷入困境,但是,计算机极其复杂,而且通常你关于什么会表现更好的直觉完全是错误的。

结果是“最干净”的代码,定义为:最容易阅读,最容易理解,误导的可能性最低,抽象且易于连接到代码库的其他部分,因此易于测试,在未来的变化下具有鲁棒性不可避免地会到达的请求 - 这是最快的代码。

实际上,99% 的资源(CPU 和 RAM)都花在了不到 1% 的代码上。然而,通常不可能猜出那 1% 是什么。因此,您构建应用程序时无需担心细节性能(即,您所做的与处理此问题时所做的完全相反),然后启动它。

如果

它比你想象的要慢(大如果),你运行一个探查器,它会告诉你那 1% 是在哪里——“热路径”。然后你就可以优化它了。如果您的代码库按照上面的定义是“干净”的,那么这很容易,如果不是,则非常困难,因此,“性能更好”极其挑剔、抽象得很糟糕、难以集成的代码是

更慢 - 因为它变得复杂优化热路径,这是唯一重要的事情。

© www.soinside.com 2019 - 2024. All rights reserved.