Skip to content

Performance improvements to the macro #198

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

Merged
merged 9 commits into from
Aug 6, 2018
Merged

Conversation

retronym
Copy link
Member

@retronym retronym commented May 4, 2018

Avoid boxing

Don't box state IDs in collections.

Avoid needless string to name conversion

  • Introduce a per-Global store of names
  • Avoid double freshening names
  • Use $async$ in all names to avoid clashes with, e.g. lambda lifted methods.

Rework dead state elimination to happen as part of expr builder

If we're in the expr position of a block, the nested state
generation can reuse the successor state.

Also, output .dot graph of state machine in verbose mode.

Sample: https://gist.github.com/88225478b11c118609b9348d61e13630

View with a local Graphviz install or http://graphviz.it/#/gallery/unix.gv

Sample generated from late expansion of:

val result = run(
  """
    import scala.async.run.late.{autoawait,lateasync}
    case class FixedFoo(foo: Int)
    class Foobar(val foo: Int, val bar: Double) {
      def guard: Boolean = true
      @autoawait @lateasync def getValue = 4.2
      @autoawait @lateasync def func(f: Any) = {
        ("": Any) match {
          case (x1, y1) if guard => x1.toString; y1.toString
          case (x2, y2) if guard => x2.toString; y2.toString
          case (x3, y3) if guard => x3.toString; y3.toString
          case (x4, y4) =>
             getValue; x4.toString; y4.toString
        }
      }
    }
    object Test {
      @lateasync def test() = new Foobar(0, 0).func(4)
    }
    """)

@retronym retronym changed the title Rework dead state elimination to happen as part of expr builder Performance improvements Jun 7, 2018
retronym added 2 commits June 7, 2018 15:16
  - Introduce a per-Global store of names
  - Avoid double freshening names
  - Use $async$ in all names to avoid clashes with, e.g. lambda lifted methods.
If we're in the expr position of a block, the nested state
generation can reuse the successor state.

Also, output .dot graph of state machine in verbose mode.

Sample: https://gist.github.com/88225478b11c118609b9348d61e13630

View with a local Graphviz install or http://graphviz.it/#/gallery/unix.gv

Sample generated from late expansion of:

    val result = run(
      """
        import scala.async.run.late.{autoawait,lateasync}
        case class FixedFoo(foo: Int)
        class Foobar(val foo: Int, val bar: Double) {
          def guard: Boolean = true
          @autoawait @lateasync def getValue = 4.2
          @autoawait @lateasync def func(f: Any) = {
            ("": Any) match {
              case (x1, y1) if guard => x1.toString; y1.toString
              case (x2, y2) if guard => x2.toString; y2.toString
              case (x3, y3) if guard => x3.toString; y3.toString
              case (x4, y4) =>
                 getValue; x4.toString; y4.toString
            }
          }
        }
        object Test {
          @lateasync def test() = new Foobar(0, 0).func(4)
        }
        """)
@retronym
Copy link
Member Author

retronym commented Jun 7, 2018

TODO:

  • Where is State 19 in the demo? I thought the state IDs were compacted by construction.
  • Add an API for the a plugin phase that use the macro implementation to selectively generate the dot
  • Print the code snippets with the rewritten states IDs, we shouldn't see stateMachine$async.this.state$async = -11206
  • Print the input source code in a text box at the top of the diagram.

@retronym retronym changed the title Performance improvements Performance improvements to the macro Jun 8, 2018
@retronym
Copy link
Member Author

retronym commented Jun 8, 2018

I've improved the .dot output.

  • The compacted state IDs are shown in the code snippets (the same ones that appear in the generated code)
  • Code is left justified, and the enclosing block is elided
  • Two nodes are shown for async boundaries (that's why state 19 appeared to be missing above). The edge between them is styled differently to show that it is async.

Updated sample: https://gist.github.com/bbd3312404a9259e4c0f0135bf5d34e3

@retronym retronym self-assigned this Jun 8, 2018
@retronym retronym merged commit b662af6 into scala:master Aug 6, 2018
@retronym retronym added this to the 0.10 milestone Apr 8, 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 this pull request may close these issues.

1 participant