Skip to content

[Perf] Cache paths and writability are re-resolved from the environment on every fetch #50

Description

@egg82

What problem are you trying to solve?

Two related costs on the hot path.

Cache paths. getBasePath re-reads and re-parses the environment every time it's called:

Lib/src/main/java/me/egg82/arr/common/AbstractArrAPI.java:325-326

private <T extends FetchableAPIObject> @NotNull File getBasePath(@NotNull Class<T> type) {
    File base = CacheConfigVars.getFile(CacheConfigVars.CACHE_DIR);

Lib/src/main/java/me/egg82/arr/config/CacheConfigVars.java:54-56

public static @NotNull File getFile(@NotNull CacheConfigVars var) {
    return FileParser.parse(var.def(), System.getenv(var.name()), true);
}

getBasePath is called at eight sites in AbstractArrAPI (lines 255, 260, 274, 282, 293, 298, 312, 320), and each cache operation hits two of them, then chains two more new File(parent, name).

Writability. isCacheWritable() re-probes on every fetch - lines 69, 111, 121, 166 - and the probe reads and re-parses touch.json through the full JSONFile.read() round-trip each time. There are two more copies of the same probe in App, in UpdateManagerImpl and Main.

What would you like Fetcharr to do?

Environment configuration is immutable for the process lifetime, and whether the cache directory is writable doesn't change between fetches. Both should be resolved once.

Optional additional context or use case that could be helpful

An earlier version of this finding cited 67,092 live java.io.File instances. That number came from GC.class_histogram -all, which counts unreachable objects too - it's churn, not retention. The allocation is real; calling it retained was wrong.

The broader version of this is that every config accessor is System.getenv plus a re-parse. The updaters hoist their lookups to locals once per cycle, which is fine - it's the API layer that doesn't, so the cost lands on every fetch. Reading the environment once into a record at startup would cover all of it.

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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions