2010-08-06 4 views
2

Предположим, я выполняю ни один из приведенных ниже фрагментов кода для списка 1000 Event записей (в allEventsToAggregate). Я видел бы улучшение производительности в первой реализации, если события в allEventsToAggregate отсортированы по customerId, причем каждый клиент имеет примерно 3 события? Это, по существу, вопрос сравнения строк с HashMap.Производительность дополнительных строк сравнения vs HashMap lookups

Вариант 1:

Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>(); 
List<Event> thisCustEntries; 
String lastCust = null; 
for (Event thisEvent : allEventsToAggregate) { 
    if (!thisEvent.getCustomerId().equals(lastCust)) { 
     thisCustEntries = eventsByCust.get(thisEvent.getCustomerId()); 
     if (thisCustEntries == null) { 
      thisCustEntries = new ArrayList<Event>(); 
     } 
    } 
    thisCustEntries.add(thisEvent); 
    eventsByCust.put(thisEvent.getCustomerId(), thisCustEntries); 
    lastCust = thisEvent.getCustomerId(); 
} 

Вариант 2:

Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>(); 
for (Event thisEvent : allEventsToAggregate) { 
    List<Event> thisCustEntries = eventsByCust.get(thisEvent.getCustomerId()); 
    if (thisCustEntries == null) { 
     thisCustEntries = new ArrayList<Event>(); 
    } 
    thisCustEntries.add(thisEvent); 
} 

ответ

3

ли я вижу улучшения производительности

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

Следовательно, я бы пошел со второй версией кода, так как его более четкое выражение ваших намерений и, следовательно, будет легче поддерживать (а также быть немного менее склонным к тонким ошибкам в первую очередь). Ремонтопригодность почти наверняка козырей делает приложение на 0,001% быстрее.

+1

Это тоже моя мысль. Просто ради любопытства, я действительно удивляюсь, в какой момент это будет иметь значение. Что, если куски клиентов События составляли около 1000 человек, а мои общие записи составляли 1 миллион? – pkananen

+0

@pkananen: Точка, в которой это имеет значение, - это точка, в которой профилирование приложения показывает, что в этом конкретном фрагменте кода тратится нематериальное количество времени, и вам 1) нужно ускорить работу и 2) не может получить столько «взрыва для вашего доллара», оптимизируя любые другие горячие точки. ;-) –

+0

Да, я согласен. Это был скорее теоретический вопрос. – pkananen

2

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

2) Мы, кажется, говорим о очень небольших различиях во времени выполнения, а не о реальных алгоритмических улучшениях. Действительно ли стоит потерять удобочитаемость для этого?

3) Для небольших отличий единственный способ узнать действительно будет на самом деле время на практике - на самом деле не только провести сравнение, но и организовать его как полноценный научный эксперимент. В наши дни слишком много беспокоиться о том, что ваш компилятор и система времени выполнения решили оптимизировать, что означает кэширование процессора или ошибка страницы VM, и то, что Java-мусорная коллекция думает о вашем алгоритме. Тогда, конечно, вы вполне можете найти, что у вас есть разные ответы на разные версии Java или на аппаратное обеспечение с различными процессорами, материнскими платами или памятью, или даже на сколько времени система работает, и поэтому сколько времени у нее было переносить содержимое своего диска в кеш памяти или JIT-компилировать соответствующие биты Java или что-то еще.

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