2013-12-21 2 views
0

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

Мне пришло в голову, что equals этих объектов довольно медленно (и привыкает много), и что я на самом деле не нужно, так как a.equals(b) эквивалентно a == b после интернирования. К сожалению, сам Interner использует equals, поэтому я должен переопределить его для одноразового использования.

Интересно, есть ли простой способ иметь равных и есть?


Отказ от ответственности: Я знаю о root of all evil, и я не уверен, что, если оптимизация на этом месте стоит усилий. Тем не менее, меня интересует, имеет ли вышеупомянутая проблема хорошее решение.

ответ

1

Это зависит от вашего шаблона использования относительно того, где вы хотите получить удар производительности.

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

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

Профилирование кода, использующего оба подхода, также может помочь вам принять это решение.

Редактировать добавить: Это говорит, что я удивлен, что их интернер полагается исключительно на equals(). В моей голове было бы более целесообразно полагаться на hashcode() и использовать только equals() для столкновений.

+0

Я не имел в виду, что 'Interner' полагается * исключительно * на equals, это своего рода хэш-карта (на самом деле карта карты MapMaker). Но это единственная причина, по которой мне нужно «равно». Я бы предпочел не переопределять равные из-за его использования на других картах. – maaartinus

+0

Правильно, это разумный способ сделать это. Это означает, что единственный раз, когда вызывается 'equals()', находится на хеш-столкновении, что означает, что редко предоставляется приемлемый метод 'hashcode()' (в зависимости от количества ковшей). И если вы переопределяете 'hashcode()' ... вам нужно переопределить 'equals()' ... для этой же цели в других картах (:: confused: :) –

1

Если ваш метод equals использует «a == b» внутри, это достаточно быстро?

class BigObject { 
    public boolean equals(Object o) { 
    if(o == this) return true; 
    if(o == null) return false; 
    // a bunch of other stuff 
    } 
} 

В качестве следующего шага, вы могли бы рассмотреть обертывание «кучу других вещей» в (частном) метод, который будет способствовать равно быть встраиваемыми. Трудно узнать, когда этот материал работает, но ...

+0

Я не думаю, что вложение 'равно 'будет работать в соответствующих местах (' HashMap # get' и т. д.), поскольку в программе есть другие карты, а 'equals' сильно перегружен. – maaartinus

Смежные вопросы