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

make Visitor not satisfy WideningTransformer #109

Closed
wants to merge 1 commit into from

Conversation

jvasileff
Copy link
Member

For consideration/discussion.

When working on #107, I noticed that WideningTransformer<Null>s used as visitors perform better than Visitors. Prior to #107, timings where 63.31ms for the transformer, and 79.72ms for the visitor. I assume this is due to the extra object created by the Java backend for interfaces with default methods and the extra layer of indirection.

With this patch, the visitor takes only 28.33ms vs. 41.49ms for the visitor after #107. So there is a significant performance boost that would be meaningful to code that runs several passes of a visitor.

Now, this still isn't as fast as the typechecker's visitor, which I can only guess attains its speed from 1) being an abstract class rather than a delegate object, and/or 2) having void methods rather than Object-returning methods. These aren't things we can address.

The raw numbers:

-------------------
Initial (1.2.0 ast)
-------------------
countNodesTransformerNull:         63.31ms (control)
countNodesVisitor:                 79.72ms
countNodesTcVisitor:               14.76ms (control)

------------------------------
With visitor optimization #107
------------------------------
countNodesTransformerNull:         56.96ms (control)
countNodesVisitor:                 41.49ms
countNodesTcVisitor:               14.91ms (control)

-----------------
With fast-visitor 
-----------------
countNodesTransformerNull:         59.25ms (control)
countNodesVisitor:                 28.33ms
countNodesTcVisitor:               14.94ms (control)

Visitors that satisfy WideningTransformer turn out to be measurably slower than
WideningTransformer's themselves. This commit makes Visitor independent of
WideningTransformer for a nice speed boost.

Steps to recreate the bulk of this patch:

1. Open the nodes in vi:
    vi `grep -l 'shared actual Result transform' * \
        | grep -v SelfReference`

2. Record a macro:
    - qq // start recording
    - /shared actual Result transform // find transform()
    - <shift-v>jjy // highlight & copy
    - jj // move down
    - p // paste
    - DAshared actual void visit(Visitor visitor)
    - <esc>j
    - :s/transformer/visitor
    - :s/transform/visit
    - jhhhD // whitespace
    - q // stop recording

3. Undo changes (uuuuuuuuuuuuu)

4. Move to top of file (:1)

5. Execute macro on all files:
    :bufdo execute "normal @q" | write

6. :q

7. Manually fix
    - SelfReference.ceylon
    - Identifier.ceylon
@lucaswerkmeister
Copy link
Member

I want to have this change in 1.2.1, but I can’t merge this PR because it touches virtually every file in source/ceylon/ast/core, so it doesn’t apply right now, and even if I merged a fixed version right now, it could break when I made more changes in independent branches.

I think I’ll make this change right before the release, when everything else is already done. And, importantly, source-gen will have to be updated as well, to produce the extra visit method.

@jvasileff how did you produce this patch? Not manually, I hope…

@lucaswerkmeister lucaswerkmeister self-assigned this Jan 20, 2016
@lucaswerkmeister lucaswerkmeister added this to the Next release milestone Jan 20, 2016
@jvasileff
Copy link
Member Author

how did you produce this patch? Not manually, I hope…

see the commit message for the precise steps 😄

@lucaswerkmeister
Copy link
Member

Whoa. Nice! Thanks!

I had avoided looking at the commit message because it also makes GitHub load the huge patch :D

@lucaswerkmeister
Copy link
Member

We could also provide this class:

shared abstract class AbstractVisitor() satisfies Visitor {}

If your visitors extend that class instead of satisfying Visitor, the compiler doesn’t have to generate a thousand methods that just delegate to Visitor$impl. If you have a lot of visitors, this might have a significant impact on bytecode size – AbstractVisitor.class is 100K.

@jvasileff
Copy link
Member Author

Interesting idea (AbstractVisitor)

I gave it a try to see if it would help with hotspot (less code to optimize). But it didn't seem to make a difference.

Since this is something space conscious users can do on their own, I think I'd probably wait to see what happens with the Java 8 version of the compiler.

@lucaswerkmeister
Copy link
Member

Yeah, once we compile to Java 8’s default interfaces this should be obsolete anyways.

lucaswerkmeister added a commit that referenced this pull request Feb 4, 2016
We now need to generate a visit method as well.
lucaswerkmeister added a commit that referenced this pull request Feb 4, 2016
make Visitor not satisfy WideningTransformer

Commit rebased onto master (redoing the bulk of the patch as described
in the commit message). Also added a commit to update source-gen.
@lucaswerkmeister
Copy link
Member

Merged in 3fc1045.

@lucaswerkmeister
Copy link
Member

Oops, wasn’t quite done yet.

lucaswerkmeister added a commit that referenced this pull request Feb 4, 2016
We now need to generate a visit method as well.
lucaswerkmeister added a commit that referenced this pull request Feb 4, 2016
make Visitor not satisfy WideningTransformer

Commit rebased onto master (redoing the bulk of the patch as described
in the commit message). Also added a commit to update source-gen.
@lucaswerkmeister
Copy link
Member

Now done in 5cd395b, I hope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants