Я хочу использовать рефлексию или интроспекцию в java для замены инструкциями «IF-ELSE», я хочу знать, насколько это дорогостоящие заявления «Reflexion» VS «IF-ELSE»? и что более эффективно, если я использую цикл с aprox 700 000 итераций?Насколько дорогим является рефлексия или интроспекция в java
ответ
См Effective Java, пункт 53: Предпочитают интерфейсы для отражения страдающей
Performance. Вызов рефлексивного метода намного медленнее, чем вызов нормального метода. Точно, насколько медленнее сказать, потому что так много факторов на работе. На моей машине разница в скорости может быть малой величиной в два или в пятьдесят раз.
Спасибо за ваш ответ – kakashy
Я нахожу thisdocumentation, и я понимаю, что риск в
Проблема с условиями, как вы могли бы знать, что они калечат предсказуемость особенности процессоров. Это означает, что предварительная выборка фактически превратится в недостаток, если это неверно. Это то, что происходит в современных процессорах, когда они не знают, что может быть результатом сравнения, поэтому они ставка. В заявлении IF-ELSE процессор имеет 50% вероятность правильного предсказания следующей команды, которая должна быть выполнена. Если нам повезет, мы выполняем больше инструкций за цикл, если мы этого не делаем, мы получаем среду штрафа за ~ 16 циклов, чтобы процессор мог восстановиться из-за неправильной предварительной выборки.
Это говорит о продолжении размышлений. Отражение - это среднее значение, для вас важна производительность. В большинстве случаев отражение и адресный вызов - C_reflection = 3*C_address_call
. В Java это еще хуже, и у меня нет официальных данных об этом. Самая большая проблема - разрешение имен/адресов/доступности.
Это говорит о том, что позволяет перейти в реальный мир и увидеть некоторые цифры. Как мы теперь можем понять, оправдать и даже предсказать результаты.
Мы тестируем 2 класса, 3 теста. В общей сложности 10M calls/test | 5M вызовов в классе:
- Условный
- Reflection
- Common Interface
И это число в секундах:
Условия - 0,022333
Отражение - 3.02087
Интерфейс - 0,012547
Так общий интерфейс является победителем в вашем случае, второй приходит условный вызов почти вдвое время выполнения (для указанных выше причин). И последний с чрезвычайно заметной разницей приходит к размышлению.
Вот код тестовой *:
import java.lang.reflect.InvocationTargetException;
public class JavaReflectionTest {
public interface ClassInterface {
public void execute();
public String getCount();
}
public static class ClassOne implements ClassInterface {
int count = 0;
public String getCount(){
return String.valueOf(count);
}
public void execute(){
count++;
}
}
public static class ClassTwo implements ClassInterface {
int count = 0;
public String getCount(){
return String.valueOf(count);
}
public void execute(){
count++;
}
}
public static void main(String[] args) throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException, ClassNotFoundException, InterruptedException {
ClassOne one = new ClassOne();
ClassTwo two = new ClassTwo();
ClassInterface ione = new ClassOne();
ClassInterface itwo = new ClassTwo();
long stopT;
long startT;
int i;
int mod;
//Warm up
for(i=0;i<350000;i++){
one.execute();
two.execute();
ione.execute();
itwo.execute();
one.getClass().getMethod("execute").invoke(one,null);
two.getClass().getMethod("execute").invoke(two,null);
}
//Test conditional call
one = new ClassOne();
two = new ClassTwo();
Thread.sleep(1000);
startT=System.nanoTime();
for(i=0;i<10000000;i++){
mod=i%2;
if(mod==0)
one.execute();
else
two.execute();
}
stopT=System.nanoTime();
System.out.println("Conditions - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount());
//Test reflection
one = new ClassOne();
two = new ClassTwo();
Thread.sleep(1000);
startT = System.nanoTime();
for(i=0;i<5000000;i++){
mod=i%2;
one.getClass().getMethod("execute").invoke(one,null);
two.getClass().getMethod("execute").invoke(two,null);
mod=i%2;
}
stopT=System.nanoTime();
System.out.println("Reflection - " + ((stopT-startT)/1000000000.0f)+ " Calls 1: " + one.getCount() + " Calls 2: " + two.getCount());
//Test common interface
ione = new ClassOne();
itwo = new ClassTwo();
Thread.sleep(1000);
startT = System.nanoTime();
for(i=0;i<5000000;i++){
mod=i%2;
ione.execute();
itwo.execute();
mod=i%2;
}
stopT=System.nanoTime();
System.out.println("Interface - " + ((stopT-startT)/1000000000.0f) + " Calls 1: " + ione.getCount() + " Calls 2: " + itwo.getCount());
}
}
- перед созданием тестов производительности, мы должны быть уверены в том, что компилятор будет оптимизировать/изменить наш код как можно меньше, это объясняет некоторые из в тесте, которые вы, возможно, не найдете интуитивно понятными.
- 1. Насколько дорогим является Thread.getStackTrace()?
- 2. Насколько дорогим является преобразование кодировки строки java?
- 3. Насколько дорогим является именованный канал (fifo)?
- 4. Насколько дорогим является склейка двоичных файлов (list_to_binary)?
- 5. Насколько дорогим является запрос с точки зрения табличного пространства TEMP?
- 6. Насколько дорогим является листинг GUID и сравнение с сравнением строк
- 7. Непонятная рефлексия Java
- 8. Является ли NSTimer дорогим?
- 9. Является RedirectToAction в C# дорогим?
- 10. Является ли чтение SharedPreferences дорогим?
- 11. Является ли context.getSystemService() дорогим звонком?
- 12. Является GETDATE() дорогим, как DateTime.Now?
- 13. Является ли счет (*) действительно дорогим?
- 14. Интроспекция Java-пакета
- 15. Является ли рефлексия нарушением принципа инкапсуляции?
- 16. Явная рефлексия против Jess
- 17. Насколько зрелым является dblinq?
- 18. Интроспекция метода Java от JRuby
- 19. Реализация LRU с меткой времени: насколько дорогим является память и загрузка памяти?
- 20. Является ли RelativeLayout более дорогим, чем LinearLayout?
- 21. Является ли SQL DATEDIFF (год, ..., ...) дорогим вычислением?
- 22. Является ли CURL дорогим сравнением file_get_contents()?
- 23. Является ли ElastiCache от Amazon дорогим?
- 24. Является ли листинг enum int int дорогим?
- 25. Насколько зрелым является java.lang.instrument?
- 26. Насколько зрелым является Эсэя или Сиена?
- 27. Интроспекция карты
- 28. Насколько масштабируемым является Jetty?
- 29. Насколько мощным является winRT?
- 30. Насколько надежным является window.location.hostname?
Почему вы не испытываете это самостоятельно? –
Проведите несколько тестов и оцените результаты. –