8000 Optimize the number of `Transformer` instances during product transformations · Issue #16 · arainko/ducktape · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Optimize the number of Transformer instances during product transformations #16
Closed
@arainko

Description

@arainko

example:

import io.github.arainko.ducktape.*
import io.github.arainko.ducktape.Transformer.ForProduct

case class Person(int: Int, str: String, inside: Inside)
case class Person2(int: Int, str: String, inside: Inside2)

case class Inside(str: String, int: Int, inside: EvenMoreInside)
case class Inside2(int: Int, str: String, inside: EvenMoreInside2)

case class EvenMoreInside(str: String, int: Int)
case class EvenMoreInside2(str: String, int: Int)

val transformed =  Person(1, "2", Inside("2", 1, EvenMoreInside("asd", 3))).to[Person2]

In the current version the generated code is kind of allocation heavy in regards to transformers, let's take a look at what is generated (Output of DebugMacros.code):

to[Person](Person.apply(1, "2", Inside.apply("2", 1, EvenMoreInside.apply("asd", 3))))[Person2](
    (((from: Person) => 
      (new Person2(
        int = from.int,
        str = from.str,
        inside = (
          ((`from₂`: Inside) => 
            (new Inside2(
              int = `from₂`.int,
              str = `from₂`.str, 
              inside = (
                ((`from₃`: EvenMoreInside) => 
                  (new EvenMoreInside2(
                    str = `from₃`.str,
                    int = `from₃`.int
                  ): EvenMoreInside2)): ForProduct[EvenMoreInside, EvenMoreInside2]
              ).transform(`from₂`.inside)
            ): Inside2)): ForProduct[Inside, Inside2]).transform(from.inside)): Person2)): ForProduct[Person, Person2])
    )

We can see that for each 'sub-transformation' we allocate a new transformer to then just call transform and get the result, we can simplify it by extracting the inside of the Transformer lambda and calling it directly, so after optimizations this code should look like this:

to[Person](Person.apply(1, "2", Inside.apply("2", 1, EvenMoreInside.apply("asd", 3))))[Person2]((((from: Person) =>
    (new Person2(
      int = from.int,
      str = from.str,
      inside = new Inside2(
        int = from.inside.int,
        str = from.inside.str,
        inside = new EvenMoreInside2(
          str = from.inside.inside.str,
          int = from.inside.inside.int
        )
      )
    ): Person2)
  ): ForProduct[Person, Person2]))

So pretty much something we'd write by hand, this optimization can also be done on ToAnyVal and FromAnyVal transformers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0