Оптимизация создания объектов внутри циклов - PullRequest
1 голос
/ 16 ноября 2009

Что из следующего было бы более оптимальным для виртуальной машины Java 6 HotSpot?

final Map<Foo,Bar> map = new HashMap<Foo,Bar>(someNotSoLargeNumber);    
for (int i = 0; i < someLargeNumber; i++)
{
  doSomethingWithMap(map);
  map.clear();
}

или

final int someNotSoLargeNumber = ...;
for (int i = 0; i < someLargeNumber; i++)
{
  final Map<Foo,Bar> map = new HashMap<Foo,Bar>(someNotSoLargeNumber);      
  doSomethingWithMap(map);
}

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

Интуитивно кажется, что первый будет лучше, поскольку есть только один «новый». Однако, учитывая, что ссылка на карту не удерживается, HotSpot сможет определить, что карта одного и того же размера (Entry [someNotSoLargeNumber] внутренне) создается для каждого цикла, а затем использовать один и тот же блок памяти (т.е. не делать много памяти, просто обнуление, которое может быть быстрее, чем вызов clear () для каждого цикла)?

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

Ответы [ 2 ]

7 голосов
/ 16 ноября 2009

Не тратьте свое время на такие микрооптимизации, если ваш профилировщик не скажет, что вам следует это делать. В частности, Sun утверждает, что современные сборщики мусора очень хорошо справляются с недолговечными объектами, а new () становится все дешевле и дешевле

1 голос
/ 16 ноября 2009

Это довольно тесная петля над «довольно большим числом», поэтому, как правило, я бы сказал, переместите экземпляр за пределы цикла. Но в целом, я думаю, вы не заметите большой разницы, так как я готов поспорить, что ваша doSomethingWithMap займет большую часть времени, чтобы GC наверстал упущенное.

...