Repository navigation
perf: reduce analytics page load — DB filter, parallel costs, merged queries #1038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -128,8 +128,14 @@ export async function computeAnalytics( | |
| } | ||
| } | ||
|
|
||
| // Pre-fetch all costs in parallel — avoids N sequential async round-trips | ||
| const entryCosts = await Promise.all( | ||
| entries.map((e) => calculateCost(e.provider, e.model, e.tokens).catch(() => 0)) | ||
| ); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While Consider fetching all unique pricing records once at the start of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| // ---- Single pass over filtered entries for everything else ---- | ||
| for (const entry of entries) { | ||
| for (let i = 0; i < entries.length; i++) { | ||
| const entry = entries[i]; | ||
| const pt = entry.tokens?.input ?? entry.tokens?.prompt_tokens ?? 0; | ||
| const ct = entry.tokens?.output ?? entry.tokens?.completion_tokens ?? 0; | ||
| const totalTkns = pt + ct; | ||
|
|
@@ -138,13 +144,7 @@ export async function computeAnalytics( | |
| const dayOfWeek = entryDate.getDay(); | ||
| const modelShort = shortModelName(entry.model); | ||
|
|
||
| // Cost | ||
| let cost = 0; | ||
| try { | ||
| cost = await calculateCost(entry.provider, entry.model, entry.tokens); | ||
| } catch { | ||
| /* ignore */ | ||
| } | ||
| const cost = entryCosts[i]; | ||
|
|
||
| // Summary | ||
| summary.promptTokens += pt; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of
SUM(CASE ... END)andAVG(CASE ... END)is a great way to merge multiple queries. However, note that if no rows match theWHEREclause, these aggregates will returnNULLin SQLite. While your current code handles this with the null-coalescing operator (?? 0) on lines 44-48, usingCOALESCE(SUM(...), 0)directly in the SQL would be slightly cleaner and more robust.