Skip to content

[Optimization] Memorize repeated selections inits/allocations #368

Description

@AlexanderGH

We have a large schema and some very large queries, and we have a lot of repeated instances if this in our selections:

private val __onFoo_Bar1: List<CompiledSelection> = listOf(
        CompiledField.Builder(
          name = "id",
          type = GraphQLID.type.notNull()
        ).build()
      )

  private val __onFoo_Bar2: List<CompiledSelection> = listOf(
        CompiledField.Builder(
          name = "id",
          type = GraphQLID.type.notNull()
        ).build()
      )

  private val __onFoo_Bar:3 List<CompiledSelection> =
      listOf(
        CompiledField.Builder(
          name = "id",
          type = GraphQLID.type.notNull()
        ).build()
      )

That's 3 list allocations, 3 builder allocations, 3 notnull allocations, and 3 final object allocations for what would be 1 list + 1 compiledfield allocations in the example above (in our real case, we have a lot more of these, so it adds up) in they are the same thing.

To optimize, i'd suggest:

  • having a single memoized instance for nonnull types, e.g. memoize a single GraphQLID.type.notNull() (and other types) and us it across all generated code.
  • avoiding builders and just calling the data class constructor directly
  • finding the same/re-used constructor calls, and then re-using that instance.

While this seems like a microp=optimization, and i might agree for smaller schemas and/or human written code, since this is generated, it should imobe as optimized as possible, since this will generally be on the critical path of many queries. In our case it's on thw critical path of loading the initial data for the first screen in the app.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions