Skip to content

[Perf] selectOne() recomputes every weight on every pick #49

Description

@egg82

What problem are you trying to solve?

App/src/main/java/me/egg82/fetcharr/util/WeightedRandom.java:47-53, 75-76

Each call allocates a fresh long[] of N and recomputes all N weights - when at most one weight changed since the last call. Each weight computation does two Duration.between allocations to read a single number.

It's called up to 100 times per cycle (the attempt cap), over the full candidate set. Benchmarked at 0.735 ms/call, 73.5 ms per cycle, ~4 MB of transient garbage on a 31,053-item set.

Worth being precise about what this is and isn't: it was originally reported as the #1 CPU cost on the strength of being the #1 allocation hot spot in a profiler. Those aren't the same measurement, and the JSON parsing work is substantially larger. This is a real but second-order cost.

What would you like Fetcharr to do?

Picking from a weighted set shouldn't be O(N) per pick when the weights are stable between picks.

Build the cumulative-weight array once per cycle and binary-search each pick - O(N) to O(log N). A Fenwick tree if you want cheap point updates as items are consumed.

Separately, and independent of the above: Duration.between(a, b).toMinutes() allocates a Duration just to read one number. ChronoUnit.MINUTES.between(a, b) returns the same value and allocates nothing.

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