Я выполнял микробенчмаркинг некоторого кода (пожалуйста, будьте любезны) и натолкнулся на эту загадку: при чтении поля с использованием отражения вызывается метод получателя быстрее, чем чтение поля.
Простой тестовый класс:
private static final class Foo {
public Foo(double val) {
this.val = val;
}
public double getVal() { return val; }
public final double val; // only public for demo purposes
}
У нас есть два отражения:
Method m = Foo.class.getDeclaredMethod("getVal", null);
Field f = Foo.class.getDeclaredField("val");
Теперь я называю два отражения в цикле, invoke
в методе и get
в поле.Первый прогон выполняется для прогрева виртуальной машины, второй прогон выполняется с 10M итерациями. Вызов метода последовательно на 30% быстрее, но почему? Обратите внимание, что getDeclaredMethod и getDeclaredField не вызываются в цикле.Они вызываются один раз и выполняются для одного и того же объекта в цикле.
Я также попробовал несколько незначительных изменений: сделал поле не финальным, транзитивным, закрытым и т. Д. Все эти комбинации привели к статистически сходнымпроизводительность.
Редактировать: Это на WinXP, Intel Core2 Duo, Sun JavaSE build 1.6.0_16-b01, работает под jUnit4 и Eclipse.