Bug 94086 - Exploding compile time with if() statements in pointcut
Summary: Exploding compile time with if() statements in pointcut
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.0M2   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 1.5.0 M4   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-09 04:45 EDT by Simon Heinzle CLA
Modified: 2005-08-31 08:22 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Heinzle CLA 2005-05-09 04:45:22 EDT
Compile time explodes when adding if(...) statements to pointcuts.
This is the same with ajc 1.2.1 and 1.5M2 although 1.5M2 is a little bit faster,
but compile time still explodes.

Example:
    pointcut pc2() :
        (execution(* Test.a(..)) && if(sl.isEnabled()) )
        || (execution(* Test.a(..)) && if(sl.isEnabled()) )

compiled in about 1 second.

Up to 7 such conditions , eg.
    pointcut Pc7() :
        (execution(* Test.a(..)) && if (sl.isEnabled()))
        || (execution(* Test.b(..)) && if (sl.isEnabled()))
        || (execution(* Test.c(..)) && if (sl.isEnabled()))
        || (execution(* Test.d(..)) && if (sl.isEnabled()))
        || (execution(* Test.e(..)) && if (sl.isEnabled()))
        || (execution(* Test.f(..)) && if (sl.isEnabled()))
        || (execution(* Test.g(..)) && if (sl.isEnabled()));

are also compiled quite quickly (~ 3 seconds with both ajc 1.2.1 and 1.5M2).

Now, adding another condition (8 lines) causes 6 seconds compile time. Adding
yet another condition line (= 9 ex. lines) causes ~ 1 min compile time!
(10 such lines even more than 8 minutes)

Sample source code below
------------------------

// ########## Aspect.aj ###############

public aspect Aspect {
    private static final SimpleLogger sl
        = new SimpleLogger();

    pointcut PC() :
        (execution(* Test.a(..)) && if (sl.isEnabled()))
        || (execution(* Test.b(..)) && if (sl.isEnabled()))
        || (execution(* Test.c(..)) && if (sl.isEnabled()))
        || (execution(* Test.d(..)) && if (sl.isEnabled()))
        || (execution(* Test.e(..)) && if (sl.isEnabled()))
        || (execution(* Test.f(..)) && if (sl.isEnabled()))
        || (execution(* Test.g(..)) && if (sl.isEnabled()))
        || (execution(* Test.h(..)) && if (sl.isEnabled()))
        || (execution(* Test.i(..)) && if (sl.isEnabled()))
        || (execution(* Test.j(..)) && if (sl.isEnabled()))
        ;

    before() : PC() {
        sl.log("Before");
    }

    after() : PC() {
        sl.log("After");
    }
}

// ########## Test.java ###############
Comment 1 Simon Heinzle CLA 2005-05-09 04:46:27 EDT
// ########## Test.java ###############

public class Test {
        public void a() {}
        public void b() {}
        public void c() {}
        public void d() {}
        public void e() {}
        public void f() {}
        public void g() {}
        public void h() {}
        public void i() {}
        public void j() {}
        public void k() {}
        public void l() {}
        public void m() {}
        public void n() {}
        public void o() {}
        public void p() {}
}


// ########## SimpleLogger.java ###############

public class SimpleLogger {
    private boolean enabled;

    public SimpleLogger() {
        enabled = false;
    }

    public void disable() {
        enabled = false;
    }

    public void enable() {
        enabled = true;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void log(String str) {
        if (enabled) {
            System.out.println("> Log: " + str);
        }

    }

}
Comment 2 Andrew J Huff CLA 2005-05-09 07:37:42 EDT
On my machine:

Num. ifs	Compile time (seconds)
1 		3
2 		3
3 		3
4 		3
5 		3
6 		3
7 		3
8 		5
9 		25
10 		285
Comment 3 Andrew J Huff CLA 2005-05-10 06:48:42 EDT
More interesting stuff:

Num. ifs	Times IfPointcut.findResidueInternal is called
1 		2
2 		20
3 		144
4 		1040
5 		8150
6 		70452
Comment 4 Andrew J Huff CLA 2005-05-11 09:31:52 EDT
Right, Andrew Clement and I have made a patch to fix this.


It makes it run consistently in good speed.
With the new patch:

Num. ifs	Times IfPointcut.findResidueInternal is called
1 		1
2 		4
3 		9
4 		16
N		N^2
Comment 5 Andrew Clement CLA 2005-05-16 06:59:00 EDT
fix checked in, waiting on build.
Comment 6 Adrian Colyer CLA 2005-08-31 08:22:02 EDT
This bug should have been closed out in May! Has been fixed in tree for several
months...