Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the performance of failed semantic predicate #53

Closed
daniellansun opened this issue Apr 17, 2019 · 4 comments · Fixed by #55
Closed

Improve the performance of failed semantic predicate #53

daniellansun opened this issue Apr 17, 2019 · 4 comments · Fixed by #55

Comments

@daniellansun
Copy link
Contributor

daniellansun commented Apr 17, 2019

Background

When semantic predicate fails, FailedPredicateException will be thrown to change the control flow. But as we all know, filling the stack trace is expensive especially when FailedPredicateException is thrown frequently.

Proposal

I propose to override fillInStackTrace() of FailedPredicateException, and its implementation is simplified as follows:

    public synchronized Throwable fillInStackTrace() {
        return this;
    }

its default implementation is:

    public synchronized Throwable fillInStackTrace() {
        if (stackTrace != null ||
            backtrace != null /* Out of protocol state */ ) {
            fillInStackTrace(0);
            stackTrace = UNASSIGNED_STACK;
        }
        return this;
    }

Advantages & Disadvantages

  • The performance of parsing can be improved to some extent. The more semantic predicates we use, the more performance we will gain.
  • We can not get the stack trace of FailedPredicateException, but usually we do not care about its stack trace.
    If we want to address FailedPredicateException some day, we can add the state to the exception message, e.g.
setState(1126);
if (!( !SemanticPredicates.isInvalidMethodDeclaration(_input) ))
    throw new FailedPredicateException(
        this, 
        " !SemanticPredicates.isInvalidMethodDeclaration(_input),  state: " 
            + 1126 /* the state is added here */);
setState(1127);
@daniellansun
Copy link
Contributor Author

daniellansun commented Apr 17, 2019

I completed a performance experiment, which is not very strict.
The following code costs about 20ms on my local machine.

Without filling stack trace:

package stacktrace;

public class MyException extends RuntimeException {
    public MyException(String msg) {
        super(msg);
    }

    public synchronized Throwable fillInStackTrace() {
        return this;
    }

    public static void main(String[] args) {
        long b = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            try {
                throw new MyException("hello");
            } catch (MyException e) {

            }
        }
        long e = System.currentTimeMillis();

        System.out.println("## " + (e - b) + "ms");
    }
}

@daniellansun
Copy link
Contributor Author

daniellansun commented Apr 17, 2019

The following code costs about 80ms on my local machine.

With filling stack trace:

package stacktrace;

public class MyException extends RuntimeException {
    public MyException(String msg) {
        super(msg);
    }

//    public synchronized Throwable fillInStackTrace() {
//        return this;
//    }

    public static void main(String[] args) {
        long b = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            try {
                throw new MyException("hello");
            } catch (MyException e) {

            }
        }
        long e = System.currentTimeMillis();

        System.out.println("## " + (e - b) + "ms");
    }
}

@daniellansun
Copy link
Contributor Author

As you can see, about 75% time can be saved.

@daniellansun
Copy link
Contributor Author

I'll submit a PR later :-)

@daniellansun daniellansun changed the title Improve the performance of semantic predicate Improve the performance of failed semantic predicate Aug 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant