Skip to content

AeshRuntimeRunner: lazy command instantiation #612

Description

@Sanne

The following is a suggestion from my agent as it was profiling my hobby project; it seems to make sense to me?

In particular it would allow me to skip e.g. all of Jackson's engine to be initialized when someone invokes a trivial command such as '--help' :)


Problem

AeshRuntimeRunner.execute() eagerly instantiates every registered command class during AeshCommandRegistryBuilder.create(), before looking at args to determine which command will run. For a CLI app with N commands, every invocation loads all N command classes plus their transitive dependencies.

Profiling a Quarkus CLI app with ~40 command classes on JVM (Java 25, -Xlog:class+init):

  • create() triggers 112 class initializations for command + generated metadata classes (~61ms)
  • These transitively pull in ~160 more classes (Jackson, TUI framework) referenced by commands that won't run
  • Total: ~270 unnecessary class loads on every invocation, regardless of which command runs

In native image this is free (AOT-compiled), but JVM mode — used during development, CI, and on platforms without GraalVM — pays the full class-loading cost every time.

Proposed solution

The annotation processor already generates lightweight *_AeshMetadata classes carrying command names, descriptions, and option definitions as static data. The flow could be:

  1. Build a metadata-only registry from *_AeshMetadata classes (small, no constructor logic, no transitive deps)
  2. Parse the command name from args against this metadata
  3. Only instantiate the matched command class

This is a two-phase approach: route on metadata, then construct on demand.

Impact

Benefits every aesh-based CLI application. Savings scale linearly with the number of registered commands. For the profiled app, it would eliminate ~270 class loads (~61ms) from every JVM-mode invocation.

Environment: Java 25, Quarkus 3.39, aesh 3.17.2, Serial GC.

Activity

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

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