Java Hashtable put 方法减慢了我的应用程序
Posted
技术标签:
【中文标题】Java Hashtable put 方法减慢了我的应用程序【英文标题】:Java Hashtable put method slow down my application 【发布时间】:2012-01-15 14:28:37 【问题描述】:我需要做的:
Dictionary cache;
cache = new Hashtable();
this.getDocument().putProperty("imageCache", cache);
然后我有一个方法:
cache.put(url, picture);
其中图片是一个图像对象。 我是这样创建的:
public Image getSmiley(String smileyName)
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
ImageIcon myicon = new ImageIcon(getClass().getResource("/ola/smileys/" + smileyName + ".png"));
myicon.paintIcon(null, g, 0, 0);
return img;
我已经运行了一个分析,我发现当我调用这个方法“put”时,应用程序的速度非常慢。可能是什么原因?
非常感谢。
最好的问候
【问题讨论】:
什么是url
?一个字符串?
@Thilo - 我猜是URL
...看我的回答:-)
如何进行分析?也许您可以在调试模式下运行并继续进入put
方法之后,并确定哪个进程实际上减慢了应用程序
【参考方案1】:
我怀疑这可能是由于您使用 URL
类作为键类型。
URL.equals(Object)
的 javadoc 是这样说的:
如果两个 URL 对象具有相同的协议、引用等效的主机、在主机上具有相同的端口号、以及相同的文件和文件的片段,则它们是相等的。
如果两个主机名都可以解析为相同的 IP 地址,则认为两个主机是等效的;否则,如果任一主机名都无法解析,则主机名必须相等,不考虑大小写;或两个主机名都等于 null。
由于主机比较需要名称解析,因此该操作是阻塞操作。
当您使用 URL
实例作为映射中的键时,每次将键与不同的键进行比较时,您可能会触发 DNS 查找...这可能需要很长时间。
如果这是您的问题,那么您需要将映射的键类型更改为 String
或 URI
... 或其他没有昂贵的 equals(Object)
方法的东西。
【讨论】:
它会先尝试hashcode()
,它被缓存在URL类中。所以我不认为它会导致应用程序慢得令人难以置信。然而,这真的取决于“难以置信”的慢。
是的...但是如果您假设您手中的URL
实例之前没有经过哈希处理,那么hashcode()
调用将需要解析主机名。另外,如果存在哈希冲突,则需要调用equals()
......对于当前表大小。
我同意你的看法。我遇到的第一个嫌疑人也是键类的hashcode()
和equals()
方法。但我真的怀疑 hashcode()
和 equals()
是否会“令人难以置信地”减慢应用程序的速度。
这取决于主机的 DNS 查找速度。根据我的经验,它可以慢到足以被称为“令人难以置信的”减速。
你是对的。 handler.equals(this, u2)
将被调用,它会非常慢。【参考方案2】:
我只是猜测,但我认为这可能是由于必须调整底层哈希结构的大小。
当您将一个值“放入”哈希表时,一旦它达到一定的容量,它就必须扩展底层数组——否则,您最终会遇到很多哈希冲突。然而,这种数组扩展操作代价高昂——它必须为新数组分配空间并将值复制到新数组中。
一个建议是给 Hashtable 构造函数一个合理的初始容量。
【讨论】:
+1 不过也不算贵。当然,OP 并没有量化“难以置信”。【参考方案3】:“难以置信”是多少?
我无法保证它会带来多少改进,但请尝试使用HashMap
而不是Hashtable
。 HashMap
不同步,我猜你在这里不需要,因为无论如何都应该在一个线程上为你的 UI 完成。
请参阅Differences between HashMap and Hashtable? 了解有关它们之间差异的更多详细信息。
【讨论】:
这是一个中肯的建议,但不应使任何明显的性能有所不同,更不用说“令人难以置信”的东西了。 Thilo - 同意。 +1 尼克关于为地图提供初始容量的回答。【参考方案4】:我假设您正在尝试预加载缓存,以便您可以执行一些操作,例如在 JEditorPane 中显示本地图像。
我刚刚遇到了这个问题,Stephen C 正确地发现了这个问题。
原来我用的是 http:// 开头的 url,我切换到了 file:/ 开头的 url,它解决了这个问题。
这些 url 从未真正连接到,它们只是散列的唯一键,因此只需确保 URL 对象知道它不需要 DNS 查找来解析它们就足够了,并且更改为文件协议就可以了.
【讨论】:
以上是关于Java Hashtable put 方法减慢了我的应用程序的主要内容,如果未能解决你的问题,请参考以下文章