Skip to content

Add query cache hits to detailed query table #2168

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

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 46 additions & 7 deletions site/frontend/src/pages/detailed-query/page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
createTableData,
createArtifactData,
DeltaData,
TableRowData,
} from "./utils";

const loading = ref(true);
Expand All @@ -21,9 +22,10 @@ const showIncr = ref(true);
const showDelta = ref(true);

type SortDirection = "asc" | "desc";
type ColumnName = keyof TableRowData;

// Client-side sorting state
const currentSortColumn = ref<string>("timeSeconds");
const currentSortColumn = ref<ColumnName>("timeSeconds");
const currentSortDirection = ref<SortDirection>("desc");

// Computed properties for UI data
Expand Down Expand Up @@ -75,6 +77,15 @@ const tableData = computed(() => {
? Math.abs(b.executionsDelta.percentage)
: 0;
break;
case "cacheHits": // Hits
aValue = a.cacheHits;
bValue = b.cacheHits;
// Use percentage change as secondary sort for equal absolute values
aSecondary =
a.cacheHitsDelta !== null ? Math.abs(a.cacheHitsDelta.percentage) : 0;
bSecondary =
b.cacheHitsDelta !== null ? Math.abs(b.cacheHitsDelta.percentage) : 0;
break;
case "incrementalLoading": // Incremental loading (s)
aValue = a.incrementalLoading;
bValue = b.incrementalLoading;
Expand Down Expand Up @@ -116,6 +127,15 @@ const tableData = computed(() => {
? Math.abs(b.executionsDelta.percentage)
: 0;
break;
case "cacheHitsDelta": // Cache hits delta
aValue = a.cacheHitsDelta !== null ? a.cacheHitsDelta.delta : -Infinity;
bValue = b.cacheHitsDelta !== null ? b.cacheHitsDelta.delta : -Infinity;
// Use percentage as secondary sort for equal delta values
aSecondary =
a.cacheHitsDelta !== null ? Math.abs(a.cacheHitsDelta.percentage) : 0;
bSecondary =
b.cacheHitsDelta !== null ? Math.abs(b.cacheHitsDelta.percentage) : 0;
break;
case "incrementalLoadingDelta": // Incremental loading delta
aValue =
a.incrementalLoadingDelta !== null
Expand Down Expand Up @@ -173,10 +193,10 @@ function loadSortFromUrl(urlParams: Dict<string>) {
const sort = urlParams["sort"] ?? "-timeSeconds"; // Default to descending timeSeconds
// Handle sort format: either "columnName" for asc or "-columnName" for desc
if (sort.startsWith("-")) {
currentSortColumn.value = sort.substring(1);
currentSortColumn.value = sort.substring(1) as ColumnName;
currentSortDirection.value = "desc";
} else {
currentSortColumn.value = sort;
currentSortColumn.value = sort as ColumnName;
currentSortDirection.value = "asc";
}
}
Expand All @@ -203,6 +223,7 @@ async function loadData() {
base_commit: base_commit ?? null,
benchmark,
scenario,
sort_idx: "-2",
};
selector.value = currentSelector;

Expand All @@ -223,7 +244,7 @@ function populateUIData(responseData: SelfProfileResponse, state: Selector) {
}

function changeSortParameters(
columnName: string,
columnName: ColumnName,
defaultDirection: SortDirection
) {
// Toggle direction if clicking the same column, otherwise use default direction
Expand All @@ -239,7 +260,7 @@ function changeSortParameters(
storeSortToUrl();
}

function getHeaderClass(columnName: string): string {
function getHeaderClass(columnName: keyof TableRowData): string {
if (columnName === currentSortColumn.value) {
if (currentSortDirection.value === "asc") {
return "header-sort-asc";
Expand Down Expand Up @@ -439,6 +460,20 @@ loadData();
>Executions delta</a
>
</th>
<th :class="getHeaderClass('cacheHits')">
<a
href="#"
@click.prevent="changeSortParameters('cacheHits', 'desc')"
>Hits</a
>
</th>
<th v-if="showDelta" :class="getHeaderClass('cacheHitsDelta')">
<a
href="#"
@click.prevent="changeSortParameters('cacheHitsDelta', 'desc')"
>Hits delta</a
>
</th>
<th
v-if="showIncr"
:class="getHeaderClass('incrementalLoading')"
Expand All @@ -449,7 +484,7 @@ loadData();
@click.prevent="
changeSortParameters('incrementalLoading', 'desc')
"
>Incremental loading (s)</a
>Incr. loading (s)</a
>
</th>
<th
Expand All @@ -461,7 +496,7 @@ loadData();
@click.prevent="
changeSortParameters('incrementalLoadingDelta', 'desc')
"
>Incremental loading delta</a
>Incr. loading delta</a
>
</th>
</tr>
Expand All @@ -484,6 +519,10 @@ loadData();
<td v-if="showDelta">
<DeltaComponent :delta="row.executionsDelta" />
</td>
<td>{{ row.cacheHits }}</td>
<td v-if="showDelta">
<DeltaComponent :delta="row.cacheHitsDelta" />
</td>
<td v-if="showIncr">{{ row.incrementalLoading.toFixed(3) }}</td>
<td v-if="showDelta && showIncr">
<DeltaComponent :delta="row.incrementalLoadingDelta" />
Expand Down
128 changes: 62 additions & 66 deletions site/frontend/src/pages/detailed-query/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ export interface ProfileElement {
label: string;
self_time: number;
percent_total_time: number;
number_of_cache_misses?: number;
number_of_cache_hits?: number;
number_of_cache_misses: number;
number_of_cache_hits: number;
invocation_count: number;
blocked_time?: number;
blocked_time: number;
incremental_load_time: number;
}

export interface ProfileElementDelta {
self_time: number;
invocation_count: number;
number_of_cache_hits: number;
incremental_load_time: number;
}

Expand All @@ -34,7 +41,13 @@ export interface ProfileData {

export interface SelfProfileResponse {
profile: ProfileData;
base_profile_delta?: ProfileData;
base_profile_delta?: ProfileDataDelta;
}

export interface ProfileDataDelta {
totals: ProfileElementDelta;
query_data: ProfileElementDelta[];
artifact_sizes: ArtifactSize[];
}

export function toSeconds(time: number): number {
Expand Down Expand Up @@ -221,14 +234,16 @@ export interface DeltaData {
isIntegral: boolean;
}

interface TableRowData {
export interface TableRowData {
isTotal: boolean;
label: string;
timePercent: {value: number; formatted: string; title: string};
timeSeconds: number;
timeDelta: DeltaData | null;
executions: number;
executionsDelta: DeltaData | null;
cacheHits: number;
cacheHitsDelta: DeltaData | null;
incrementalLoading: number;
incrementalLoadingDelta: DeltaData | null;
}
Expand All @@ -244,85 +259,66 @@ export function createTableData(
// Add totals row first
const totals = profile.totals;
const totalsDelta = delta?.totals;
result.push({
isTotal: true,
label: totals.label,
result.push(createRowData(true, totals, totalsDelta));

// Add query data rows
profile.query_data.forEach((query, idx) => {
const queryDelta = delta?.query_data[idx];
result.push(createRowData(false, query, queryDelta));
});

return result;
}

function createRowData(
isTotal: boolean,
value: ProfileElement,
delta: ProfileElementDelta | undefined
): TableRowData {
return {
isTotal,
label: value.label,
timePercent:
totals.percent_total_time < 0
value.percent_total_time < 0
? {
value: -1,
formatted: "-",
title: "No wall-time stat collected for this run",
}
: {
value: totals.percent_total_time,
formatted: totals.percent_total_time.toFixed(2) + "%*",
value: value.percent_total_time,
formatted: value.percent_total_time.toFixed(2) + "%",
title: "% of cpu-time stat",
},
timeSeconds: toSeconds(totals.self_time),
timeDelta: totalsDelta
timeSeconds: toSeconds(value.self_time),
timeDelta: delta
? createDelta(
toSeconds(totals.self_time),
toSeconds(totalsDelta.self_time),
toSeconds(value.self_time),
toSeconds(delta.self_time),
false
)
: null,
executions: totals.invocation_count,
executionsDelta: totalsDelta
? createDelta(totals.invocation_count, totalsDelta.invocation_count, true)
executions: value.invocation_count,
executionsDelta: delta
? createDelta(value.invocation_count, delta.invocation_count, true)
: null,
cacheHits: value.number_of_cache_hits,
cacheHitsDelta: delta
? createDelta(
value.number_of_cache_hits,
delta.number_of_cache_hits,
true
)
: null,
incrementalLoading: toSeconds(totals.incremental_load_time),
incrementalLoadingDelta: totalsDelta
incrementalLoading: toSeconds(value.incremental_load_time),
incrementalLoadingDelta: delta
? createDelta(
toSeconds(totals.incremental_load_time),
toSeconds(totalsDelta.incremental_load_time),
toSeconds(value.incremental_load_time),
toSeconds(delta.incremental_load_time),
false
)
: null,
});

// Add query data rows
profile.query_data.forEach((query, idx) => {
const queryDelta = delta?.query_data[idx];
result.push({
isTotal: false,
label: query.label,
timePercent:
query.percent_total_time < 0
? {
value: -1,
formatted: "-",
title: "No wall-time stat collected for this run",
}
: {
value: query.percent_total_time,
formatted: query.percent_total_time.toFixed(2) + "%",
title: "",
},
timeSeconds: toSeconds(query.self_time),
timeDelta: queryDelta
? createDelta(
toSeconds(query.self_time),
toSeconds(queryDelta.self_time),
false
)
: null,
executions: query.invocation_count,
executionsDelta: queryDelta
? createDelta(query.invocation_count, queryDelta.invocation_count, true)
: null,
incrementalLoading: toSeconds(query.incremental_load_time),
incrementalLoadingDelta: queryDelta
? createDelta(
toSeconds(query.incremental_load_time),
toSeconds(queryDelta.incremental_load_time),
false
)
: null,
});
});

return result;
};
}

export function createArtifactData(data: SelfProfileResponse | null): {
Expand Down
1 change: 1 addition & 0 deletions site/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ pub mod self_profile {
// Nanoseconds
pub self_time: i64,
pub invocation_count: i32,
pub number_of_cache_hits: i32,
// Nanoseconds
pub incremental_load_time: i64,
}
Expand Down
5 changes: 5 additions & 0 deletions site/src/request_handlers/self_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ fn get_self_profile_delta(
self_time: profile.totals.self_time as i64 - base_profile.totals.self_time as i64,
invocation_count: profile.totals.invocation_count as i32
- base_profile.totals.invocation_count as i32,
number_of_cache_hits: profile.totals.number_of_cache_hits as i32
- base_profile.totals.number_of_cache_hits as i32,
incremental_load_time: profile.totals.incremental_load_time as i64
- base_profile.totals.incremental_load_time as i64,
};
Expand All @@ -230,6 +232,8 @@ fn get_self_profile_delta(
let delta = self_profile::QueryDataDelta {
self_time: qd.self_time as i64 - base_qd.self_time as i64,
invocation_count: qd.invocation_count as i32 - base_qd.invocation_count as i32,
number_of_cache_hits: qd.number_of_cache_hits as i32
- base_qd.number_of_cache_hits as i32,
incremental_load_time: qd.incremental_load_time as i64
- base_qd.incremental_load_time as i64,
};
Expand All @@ -240,6 +244,7 @@ fn get_self_profile_delta(
let delta = self_profile::QueryDataDelta {
self_time: qd.self_time as i64,
invocation_count: qd.invocation_count as i32,
number_of_cache_hits: qd.number_of_cache_hits as i32,
incremental_load_time: qd.incremental_load_time as i64,
};

Expand Down
Loading