Repository navigation
Conversation
…zy matching PricingMap::find() does an exact HashMap lookup followed by expensive fuzzy matching through all ~2,200 pricing entries when the exact model name is not in the map. When adapters repeatedly query the same model names, a large fraction of lookups miss the HashMap and trigger a full scan of the pricing table for every call. Add a OnceLock<Mutex<FxHashMap>> cache that memoizes find() results by model name (including None for models not found in pricing). Once a model name has been resolved, future lookups complete in O(1) instead of O(n) over the pricing table. Also add clear_find_cache() called from load_json_with_overrides(), load_models_dev_models(), and apply_overrides() so the cache stays consistent when the pricing table is mutated.
calculate_open_code_cost and missing_open_code_pricing independently iterate through the same model candidates. When the cost calculation already found a valid positive cost (either from a stored cost_usd field or from pricing lookup), skip the missing-pricing check entirely since pricing was already resolved.
|
no API key found — this repo is configured to use To fix: add the key as a GitHub Actions secret (referenced from your workflow's Open repo secrets → · Configure model → · Setup docs → · Ask in Discord →
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughTwo performance optimizations targeting slow pricing lookups: ChangesPricing Lookup Performance
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
This PR was auto-closed. Only contributors approved with Maintainers review auto-closed issues and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md may not be reopened or receive a reply. If a maintainer replies See CONTRIBUTING.md. |
|
Historical audit: this pull request was auto-closed by the legacy contributor gate. That closure did not assess technical importance. Audit result: needs review. The current state does not prove resolution, but a fresh technical or product check is required before deciding whether the underlying request is still relevant. This closed PR will not be revived as-is; create a new PR only after reviewing the related issue and current |

Closes #1344
Thank you for your interest in my PR!
Summary
bunx ccusage@latest opencodewas taking over two minutes on my machine with a large OpenCode history (~3.6 GB, 87k messages). Profiling showed thatPricingMap::find()accounted for 91% of execution time — despite only 47 unique model names being present, each of the 87k messages independently repeated the full fuzzy lookup through ~2,200 pricing entries.This PR addresses the issue with two independent optimizations:
PricingMap::find()so repeated lookups for the same model complete in O(1)Changes
rust/crates/ccusage/src/pricing.rsfind_cache: OnceLock<Mutex<FxHashMap<String, Option<Pricing>>>>toPricingMapfind()now checks the cache first; on cache miss the full lookup runs and the result (includingNonefor models not in pricing) is stored for subsequent callsclear_find_cache()called fromload_json_with_overrides(),load_models_dev_models(), andapply_overrides()to maintain consistency when the pricing table is mutatedDefaultto manual implementation to accommodate theOnceLockfieldunwrap_or_else(|error| error.into_inner())consistently across all cache operationsrust/crates/ccusage/src/adapter/opencode/parser.rscalculate_open_code_costandmissing_open_code_pricingindependently iterated the same model candidates. When cost calculation already returned a positive cost (cost > 0.0), the missing-pricing check is now skipped entirely.Benchmark
Measured on the same machine with the same 3.6 GB OpenCode history:
The cache is in the shared
PricingMaplayer, so other adapters (Claude Code, Codex, Amp, etc.) may benefit from it as well. Memory overhead is proportional to the number of unique model names looked up, typically a few kilobytes.Checklist
direnv exec . just fmtdirenv exec . just test(368/368 passed)cargo build --releasesucceedsNO_COLOR=1 TZ=UTC) between cached and uncached pathsNeed help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Cache results of
PricingMap::find()and skip redundant OpenCode pricing checks to massively speed up large runs (e.g.,ccusage opencodefrom ~122s to ~2.3s). The cache lives in the shared pricing layer, so other adapters benefit too.find()results (including misses) in anOnceLock<Mutex<FxHashMap>>keyed by model.Written for commit 82c5d84. Summary will update on new commits.
Summary by CodeRabbit