Профилирование Java: java.lang. Object.hashCode занимает половину процессорного времени, но никогда explictly названный

Я был сравнен мое multihreaded использование программы -agentlib:hprof=cpu=samples и был удивлен найти следующую строку в результатах:

rank   self  accum   count trace method
   1 52.88% 52.88%    8486 300050 java.lang.Object.hashCode

Я никогда явно называю хэш-код () в моей программе. Какова может быть причина этого? Как я могу понять источник в течение этого времени "отходы" и нормально ли это или нет?

Спасибо, David

5
задан Donal Fellows 26 June 2010 в 18:18
поделиться

2 ответа

Скорее всего, вы очень интенсивно используете карту, такую ​​как HashMap.

HashMap использовал хэш-код для распределения объектов. Если вы используете много объектов с этой структурой данных, очень важно правильно реализовать ваш метод .equals и ваш .hashCode .

См. Эффективный элемент Java 8: Всегда переопределять hashCode, когда вы переопределяете значение

5
ответ дан 14 December 2019 в 13:26
поделиться

Вы, наверное, правы. Я действительно могу отказаться от использования возможностей произвольного доступа (как вы это называете?), И меня не волнует порядок объектов. Мне просто нужно иметь возможность добавлять объекты, а затем перебирать их все. Кроме того, это действительно набор (мне не нужен один и тот же объект более одного раза), но я также никогда не буду пытаться добавить его более одного раза ... Должен ли я использовать вместо этого список (хотя меня не волнует заказ)? Какая структура данных является наиболее эффективной для такого набора?

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

Другими альтернативами являются TreeSet или (при условии, что ваше приложение никогда не будет пытаться вставить дубликат) один из классов List. Если ваше приложение таково, что список будет работать, то ArrayList или LinkedList будут более эффективными, чем HashSet или TreeSet.

Однако есть что-то очень подозрительное в том, что ваше приложение тратит 50% своего времени на методы hashCode . Если размер хэш-таблиц не изменен, метод hashCode следует вызывать только один раз для каждой операции набора или сопоставления. Так что либо происходит много изменений размера карты / набора, либо вы выполняете огромное количество операций set add . (AFAIK, метод хэш-кода объекта дешев, поэтому стоимость каждого вызова не должна быть проблемой.)

РЕДАКТИРОВАТЬ

Является ли nextInt () действительно дорогим? Есть альтернативы?

Нет, это не дорого. Взгляните на код.Класс Random (и метод nextInt ()) действительно использует AtomicLong, чтобы сделать его потокобезопасным, и вы можете сэкономить несколько циклов, если закодировали версию, не ориентированную на потоки. Исходный код находится в каталоге установки JDK ... взгляните.

0
ответ дан 14 December 2019 в 13:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: