27 августа 2010 г.

Immutable vs Mutable объекты

Когда я узнал, что final поля "гарантированно видимы любому потоку" после завершения инициализации, я подумал, что ведь это чего-то да стоит. В том смысле, что создание immutable объекта с final полями должно быть дороже (как минимум, в многопоточном окружении, чтобы JIT не смог это оптимизировать). Т.е. как минимум нужен же мембар по завершении конструктора. Сегодня попытался это проверить -- объявил два идентичных класса, у одного из которых все поля final, и создавал их в 150 потоков параллельно. Черта с два -- одинаково. Даже наоборот, есть слабое преимущество у immutable класса, но я бы не назвал его статистически значимым -- где-то 0.5%, слишком мало, чтобы принимать во внимание в случае микробенчмарка.

P.S. Постфактум это становится довольно очевидным. Семантика final полей обеспечивается StoreStore барьером между инициализацией полей и публикацией ссылки на созданный объект:

localRef = alloc(...);
localRef.field1 = ...;
localRef.field2 = ...;
....
StoreStore;
globallyAvailableRef = localRef;

Но на x86, где я тестировал, StoreStore барьер не нужен -- тамошняя "железная" модель памяти (TSO -- total store order) достаточно строгая сама по себе.

Более того, по словам DL в его кулинарной книге StoreStore барьеры, даже если они и требуются на какой-то архитектуре, обычно одни из самых дешевых. Так что, с высокой степенью вероятности, их влияние на производительность даже там, где они есть (и требуются) будет теряться на фоне, например, затрат на выделение памяти

Комментариев нет:

Отправить комментарий