Java Hashtable put метод замедляет мое приложение - PullRequest
2 голосов
/ 08 декабря 2011

Мне нужно сделать:

Dictionary cache;
cache = new Hashtable();
this.getDocument().putProperty("imageCache", cache);

Тогда у меня есть метод, который делает:

cache.put(url, picture);

Где изображение - это объект Image.Я создаю этот способ:

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", приложение невероятно замедляется.В чем может быть причина?

Большое спасибо.

С наилучшими пожеланиями

Ответы [ 4 ]

5 голосов
/ 08 декабря 2011

Я подозреваю, что это может быть связано с тем, что вы используете класс URL в качестве типа ключа.

Javadoc для URL.equals(Object) говорит это:

Два объекта URL равны, если они имеют одинаковый протокол, ссылаются на эквивалентные хосты, имеют одинаковый номер порта на хосте и один и тот же файл и фрагмент файла.

Два хоста считаются эквивалентными, если оба имени хоста могут быть преобразованы в один и тот же IP-адрес; в противном случае, если ни одно из имен хостов не может быть разрешено, имена хостов должны быть равны без учета регистра; или оба имени хоста равны нулю.

Поскольку для сравнения хостов требуется разрешение имен, эта операция является операцией блокировки.

Когда вы используете экземпляр URL в качестве ключа на карте, каждый раз, когда ключ сравнивается с другим, вы можете запускать поиск DNS ... и это может занять много времени.


Если это ваша проблема, то вам нужно изменить тип ключа карты на String или URI ... или что-то еще, что не имеет дорогого equals(Object) метода.

2 голосов
/ 08 декабря 2011

Я просто даю предположение, но я думаю, что это может быть связано с изменением размера базовой структуры хеша.

Когда вы «помещаете» значение в хеш-таблицу, когда оно достигает определенной емкости, оно должно расширить базовый массив - в противном случае вы получите множество коллизий хеш-функции.Однако эта операция расширения массива дорогая - она ​​должна выделять пространство для нового массива и копировать значения в новый массив.

Одним из предложений было бы дать разумную начальную емкость конструктору Hashtable.

1 голос
/ 08 декабря 2011

Сколько стоит "невероятно"?

Я не могу гарантировать, насколько много улучшений, но попробуйте использовать HashMap вместо Hashtable. HashMap не синхронизируется, что, я полагаю, вам здесь не нужно, так как в любом случае все должно быть сделано в одном потоке для вашего интерфейса.

См. Различия между HashMap и Hashtable? для некоторых дополнительных деталей о различиях между ними.

0 голосов
/ 01 июня 2013

Я предполагаю, что вы пытаетесь предварительно загрузить кэш, чтобы вы могли что-то сделать, например, показывать локальные изображения в JEditorPane.

Я только что столкнулся с этой проблемой, и Стивен С. правильно определил проблему.

Первоначально я использовал URL-адреса, которые начинались с http://, Я переключился на URL-адреса, начинающиеся с файла: /, и это устранило проблему.

Эти URL-адреса фактически никогда не связаны, они простоуникальные ключи для хэша, поэтому достаточно просто убедиться, что объект URL знает, что для их разрешения не требуется поиск DNS, и для этого нужно перейти на файловый протокол.

...