Производительность aop весной (idk, aspectj)

Я попытался протестировать производительность АОП на Spring framework 4.1.6 и

Методы АОП были чистыми, динамический прокси jdk и аспектJ.

Я дал им от одного до пяти простых советов и проверил, сколько времени прошло.

результат:

динамический прокси jdk:

    • аспект1: 2,499 сек.
    • аспект2: 2.574
    • аспект3: 2.466
    • аспект4: 2.436
    • аспект5: 2.563

    аспектJ (ctw):

      • аспект1: 2.648
      • аспект2: 2.562
      • аспект3: 2.635
      • аспект4: 2.520
      • аспект5: 2.574

      чистый (без аспекта):

        • аспект1: 2.699
        • аспект2: 2.513
        • аспект3: 2.527
        • аспект4: 2.458
        • аспект5: 2.402

        Перед их тестированием я ожидал, что AspectJ (ctw) будет быстрее, чем динамический прокси Jdk, потому что AspectJ модифицировал байт-код. Но это было неправильно, даже между ними не было разницы в производительности.

        Итак, я проверил измененный целевой класс (.class), чтобы распознать, что компилятор AspectJ использовал, и обнаружил, что байт-код изменен.

        Здесь у меня вопрос: есть ли разница в производительности между ними? (динамический прокси idk, aspectj, без aop)

        Мой код:

        public class HelloAOP {
        
        public static void main(String [] args) {
        
            ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/application-context.xml");
            Order order = (Order) ctx.getBean("orderImpl");
            SimpleDateFormat format = new SimpleDateFormat("mm:ss.SSS");
        
            StopWatch watch = new StopWatch();
        
            watch.start();
            order.placeOrder();
            watch.stop();
        
            System.out.println("Elapsed: " + format.format(watch.getTotalTimeMillis()));
            }
        }
        

        цель:

        @Service
        public class OrderImpl implements Order {
            public void placeOrder() {
                System.out.println("::Target Object");
                for(long i = 0; i < 5000000000L; i++);
            }
        }
        

        аспект:

        @Aspect
        @Component
        public class Aspect1 {
        
            @Before("execution(* com.cafe.beans.impl.OrderImpl.placeOrder())")
            public void aspect() {
                System.out.println("Aspect 1 *");
            }
        }
        

        pom.xml:

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>4.1.6</version>
            </dependency>
        
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>4.1.6</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-instrument</artifactId>
                <version>4.1.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.6</version>
            </dependency>
        
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.6</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjtools</artifactId>
                <version>1.8.6</version>
            </dependency>
        
        <build>
            <finalName>testAop</finalName>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>3.3</source>
                        <target>3.3</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <includes>
                            <include>**/*Tests.java</include>
                        </includes>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.7</version>
                    <configuration>
                        <showWeaveInfo>true</showWeaveInfo>
                        <verbose>true</verbose>
                        <complianceLevel>1.8</complianceLevel>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
        

        person jongseok    schedule 05.09.2015    source источник


        Ответы (1)


        Вы не должны удивляться тому, что не увидите никакой разницы, потому что вы просто измеряете один единственный вызов метода. 99,9% измеренного времени - это цикл внутри вашего метода. Следовательно, вы не измеряете то, что нужно. Вам следует сделать это наоборот, возможно, аналогично тому, что я сделал здесь:

        • Метод не должен делать ничего или почти ничего и ничего не печатать.
        • Вы должны измерить общее время многократного вызова метода с рекомендациями по аспектам, потому что вы хотите узнать об издержках применения аспекта, а не о времени выполнения тела метода (тело метода остается неизменным в зависимости от вашего аспекта).

        Теперь вы можете сравнить производительность Spring AOP с AspectJ и убедиться, что AspectJ превосходит его. Несколько предостережений:

        • Надеюсь, вы знаете, что вам нужно изменить конфигурацию Spring, чтобы переключиться с Spring AOP на AspectJ и наоборот. Например. если вы все время используете плагин AspectJ Maven для своих сборок, вы будете использовать переплетение AspectJ во время компиляции, независимо от того, настроили ли вы Spring для использования Spring AOP или AspectJ через переплетение во время загрузки, как описано в руководстве Spring, раздел 10.8 Использование AspectJ с Весенние приложения.
        • Вам следует измерить различные типы точек и советов, например _1 _ / _ 2_ по сравнению с @Around, (не) с использованием привязки параметров через this(), target() или args() и т. Д.
        • Также обратите внимание, что ваш пример кода использует pointcut для класса, а не для интерфейса. Однако динамические прокси JDK не работают напрямую с классами, а только с интерфейсами. Чтобы применить Spring AOP к классам, вам понадобится CGLIB в качестве зависимости в Spring, иначе он просто не будет работать. Изменить. Хорошо, ваш класс реализует интерфейс Order, поэтому он может по-прежнему работать с динамическими прокси JDK.
        person kriegaex    schedule 06.09.2015
        comment
        Благодаря твоему доброму совету мне это действительно помогло. и, извините, что поздно комментирую вашу помощь. - person jongseok; 16.10.2015