Java Hashtable put 方法减慢了我的应用程序的速度
我需要做:
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”时,应用程序速度显着减慢。可能是什么原因?
非常感谢。
此致
I need to do :
Dictionary cache;
cache = new Hashtable();
this.getDocument().putProperty("imageCache", cache);
Then I have a method who does :
cache.put(url, picture);
Where picture is an Image object.
I create this way :
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;
}
I have run a profiling and I have seen that when I call this method "put", the application slows down incredibly. What could be the reason ?
Thank you very much.
Best Regards
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我怀疑这可能是由于您使用
URL
类作为键类型造成的。javadoc<
URL.equals(Object)
的 /a> 表示:当您使用
URL
实例作为地图中的键时,每次将一个键与另一个键进行比较时,您都可能会触发 DNS 查找......这可能需要很长时间。如果这是您的问题,那么您需要将映射的键类型更改为
String
或URI
...或其他没有昂贵的equals(Object)
方法。I suspect that this might be due to your using the
URL
class as the key type.The javadoc for
URL.equals(Object)
says this:When you use a
URL
instance as a key in a map, then each time a key is compared to a different one you could be triggering a DNS lookup ... and that could take a long time.If this is your problem, then you need to change the key type of the map to
String
orURI
... or something else that doesn't have an expensiveequals(Object)
method.我只是给出一个猜测,但我认为这可能是由于底层哈希结构必须调整大小。
当你将一个值“放入”哈希表时,一旦它达到一定的容量,它就必须扩展底层数组——否则,你最终会遇到很多哈希冲突。然而,这种数组扩展操作的成本很高——它必须为新数组分配空间并将值复制到新数组中。
一个建议是为 Hashtable 构造函数提供合理的初始容量。
I'm just giving a guess, but I think it might be due to the underlying hash structure having to be resized.
When you're 'put'ing a value into a hashtable, once it reaches a certain capacity, it has to expand the underlying array -- otherwise, you end up getting a lot of hash collisions. However, this array expansion operation is expensive -- it has to allocate space for the new array and copy values into the new array.
One suggestion would be to give a reasonable initial capacity to the Hashtable constructor.
“难以置信”是多少?
我无法保证它会带来多大的改进,但请尝试使用
HashMap
而不是Hashtable
。HashMap
未同步,我猜您在这里不需要同步,因为无论如何,一切都应该在 UI 的单个线程上完成。请参阅 HashMap 和 Hashtable 之间的差异? 了解它们之间差异的一些其他详细信息。
How much is "incredibly"?
I can't guarantee how much of an improvement it would make, but try using
HashMap
instead ofHashtable
.HashMap
is not synchronized, which I'm guessing you don't need here, since everything should be done on a single thread for your UI anyway.See Differences between HashMap and Hashtable? for some additional details of the differences between these.
我假设您正在尝试预加载缓存,以便可以执行诸如在 JEditorPane 中显示本地图像之类的操作。
我刚刚遇到了这个问题& Stephen C 正确地识别了该问题。
最初我使用以 http:// 开头的网址,我切换到以 file:/ 开头的网址,它解决了问题。
这些 url 从未真正连接到,它们只是哈希的唯一键,因此只需确保 URL 对象知道它不需要 DNS 查找来解析它们就足够了,&更改为文件协议即可做到这一点。
I assume you're trying to pre-load a cache so you can do something like showing local images in a JEditorPane.
I just had this problem & Stephen C correctly identified the issue.
Originally I was using urls which started with http://, I switched to urls starting with file:/ and it fixed the problem.
These urls are never actually connected to, they're just unique keys for the hash so just making sure the URL object knows it doesn't need a DNS lookup to resolve them is enough, & changing to the file protocol does that.