Улучшение Comparable ‹T› сравнения с производительностью

Я профилировал свой код и обнаружил, что мой класс, реализующий Comparable<T>, тратит в 8 раз больше времени процессора в

compareTo(Object)

чем в

compareTo(T)

Я предполагаю, что замедление происходит из-за поиска этого метода в виртуальной таблице.


Есть ли способ принудительно вызвать статический вызов функции? (например, в невиртуальных методах C ++)

Я все еще хочу использовать интерфейс Comparable<T>, поскольку я использую TreeSet с этим объектом, и я не хочу переписывать этот код.


РЕДАКТИРОВАТЬ: Нет, я не реализовал compareTo (Object) - это было автоматически сгенерировано и сообщено профилировщиком


person Dani    schedule 10.03.2009    source источник
comment
И два compareTo точно такие же, кроме кастинга?   -  person Michael Myers    schedule 10.03.2009
comment
Обычно существует метод соединения, в котором compareTo (Object) вызывает compareTo (ThisConcreteType). Предположительно последний почти ничего не делает. -server может помочь встраивать вещи.   -  person Tom Hawtin - tackline    schedule 10.03.2009
comment
Сделали предварительный расчет производительности?   -  person Tom Hawtin - tackline    schedule 10.03.2009
comment
Метод моста должен автоматически генерироваться компилятором, поскольку для реализации Comparable ‹T› требуется только написать метод compareTo (T).   -  person Powerlord    schedule 10.03.2009
comment
Да, но метод моста по-прежнему выполняется и отображается в профилировщике.   -  person Tom Hawtin - tackline    schedule 10.03.2009
comment
Как вы нашли способ повысить производительность? Я с той же проблемой.   -  person killy971    schedule 13.08.2009


Ответы (4)


причина, по которой вы видите compareTo(Object), связана с Стирание типа. это просто означает, что во время выполнения информация о типе больше не нужна для сравнения значений. скорее всего, причина вашего замедления: 1) очень, очень большой TreeSet с большим количеством элементов 2) - более вероятно - ваш метод compareTo делает что-то дорогое. поскольку он вызывается очень часто (обычно n * ln (n) раз), он должен быть реализован эффективно

person Andreas Petersson    schedule 10.03.2009
comment
Я намеренно использую большой TreeSet, поэтому постарался сделать его как можно быстрее - он имеет только одно разыменование и два сравнения. - person Dani; 10.03.2009
comment
используйте treeSet только при необходимости. если вам нужно, чтобы ваш набор был отсортирован только в определенное время, советник использует HashSet и сортирует его, когда он вам нужен, а не все время. - person Andreas Petersson; 11.03.2009

Нет, в этом случае вы не можете принудительно вызвать статический вызов.

Метод экземпляра может быть вызван «не виртуально» инструкцией invokespecial. Эта инструкция используется, когда цель известна во время компиляции, например, конструктор или частный метод. В других случаях, даже когда целевой метод final, используются инструкции invokevirtual или invokeinterface.

person erickson    schedule 10.03.2009
comment
Пункт педантизма: Или, что более вероятно, в этом случае, invokeinterface, поскольку Comparable - это интерфейс. - person Tom Hawtin - tackline; 10.03.2009

Поскольку java не сохраняет общие типы во время выполнения, в идеале они оба должны вести себя одинаково. Возможно, проблема в другом.

person amit    schedule 10.03.2009

Я предполагаю, что замедление происходит из-за поиска этого метода в виртуальной таблице.

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

Мое предположение (которое может быть ошибочным) состоит в том, что он проходит девять ярдов вызова в стиле OLE, ура-ха-ха.

person Mike Dunlavey    schedule 10.03.2009