compare-perf: Add support for selecting a single run as input
A very hacky implementation that simply instantiates an empty `PerformanceOverviewScanner` as the "from" column (i.e. with all values empty). To see it in action, select a single query run in the query history and pick "Compare Performance" from the context menu. Then select the "Single run" option when prompted.
This commit is contained in:
@@ -56,8 +56,10 @@ export class ComparePerformanceView extends AbstractWebview<
|
||||
}
|
||||
|
||||
const [fromPerf, toPerf] = await Promise.all([
|
||||
scanLogWithProgress(fromJsonLog, "1/2"),
|
||||
scanLogWithProgress(toJsonLog, "2/2"),
|
||||
fromJsonLog === ""
|
||||
? new PerformanceOverviewScanner()
|
||||
: scanLogWithProgress(fromJsonLog, "1/2"),
|
||||
scanLogWithProgress(toJsonLog, fromJsonLog === "" ? "1/1" : "2/2"),
|
||||
]);
|
||||
|
||||
await this.postMessage({
|
||||
|
||||
@@ -927,7 +927,7 @@ async function activateWithInstalledDistribution(
|
||||
): Promise<void> => showResultsForComparison(compareView, from, to),
|
||||
async (
|
||||
from: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo | undefined,
|
||||
): Promise<void> =>
|
||||
showPerformanceComparison(comparePerformanceView, from, to),
|
||||
);
|
||||
@@ -1208,17 +1208,22 @@ async function showResultsForComparison(
|
||||
async function showPerformanceComparison(
|
||||
view: ComparePerformanceView,
|
||||
from: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo | undefined,
|
||||
): Promise<void> {
|
||||
const fromLog = from.evaluatorLogPaths?.jsonSummary;
|
||||
const toLog = to.evaluatorLogPaths?.jsonSummary;
|
||||
let fromLog = from.evaluatorLogPaths?.jsonSummary;
|
||||
let toLog = to?.evaluatorLogPaths?.jsonSummary;
|
||||
|
||||
if (to === undefined) {
|
||||
toLog = fromLog;
|
||||
fromLog = "";
|
||||
}
|
||||
if (fromLog === undefined || toLog === undefined) {
|
||||
return extLogger.showWarningMessage(
|
||||
`Cannot compare performance as the structured logs are missing. Did they queries complete normally?`,
|
||||
);
|
||||
}
|
||||
await extLogger.log(
|
||||
`Comparing performance of ${from.getQueryName()} and ${to.getQueryName()}`,
|
||||
`Comparing performance of ${from.getQueryName()} and ${to?.getQueryName() ?? "baseline"}`,
|
||||
);
|
||||
|
||||
await view.showResults(fromLog, toLog);
|
||||
|
||||
@@ -151,7 +151,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
) => Promise<void>,
|
||||
private readonly doComparePerformanceCallback: (
|
||||
from: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo | undefined,
|
||||
) => Promise<void>,
|
||||
) {
|
||||
super();
|
||||
@@ -706,7 +706,10 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
|
||||
let toItem: CompletedLocalQueryInfo | undefined = undefined;
|
||||
try {
|
||||
toItem = await this.findOtherQueryToCompare(fromItem, multiSelect);
|
||||
toItem = await this.findOtherQueryToComparePerformance(
|
||||
fromItem,
|
||||
multiSelect,
|
||||
);
|
||||
} catch (e) {
|
||||
void showAndLogErrorMessage(
|
||||
this.app.logger,
|
||||
@@ -714,9 +717,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
);
|
||||
}
|
||||
|
||||
if (toItem !== undefined) {
|
||||
await this.doComparePerformanceCallback(fromItem, toItem);
|
||||
}
|
||||
await this.doComparePerformanceCallback(fromItem, toItem);
|
||||
}
|
||||
|
||||
async handleItemClicked(item: QueryHistoryInfo) {
|
||||
@@ -1116,6 +1117,7 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
detail: item.completedQuery.message,
|
||||
query: item,
|
||||
}));
|
||||
|
||||
if (comparableQueryLabels.length < 1) {
|
||||
throw new Error("No other queries available to compare with.");
|
||||
}
|
||||
@@ -1124,6 +1126,60 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return choice?.query;
|
||||
}
|
||||
|
||||
private async findOtherQueryToComparePerformance(
|
||||
fromItem: CompletedLocalQueryInfo,
|
||||
allSelectedItems: CompletedLocalQueryInfo[],
|
||||
): Promise<CompletedLocalQueryInfo | undefined> {
|
||||
const dbName = fromItem.databaseName;
|
||||
|
||||
// If exactly 2 items are selected, return the one that
|
||||
// isn't being used as the "from" item.
|
||||
if (allSelectedItems.length === 2) {
|
||||
const otherItem =
|
||||
fromItem === allSelectedItems[0]
|
||||
? allSelectedItems[1]
|
||||
: allSelectedItems[0];
|
||||
if (otherItem.databaseName !== dbName) {
|
||||
throw new Error("Query databases must be the same.");
|
||||
}
|
||||
return otherItem;
|
||||
}
|
||||
|
||||
if (allSelectedItems.length > 2) {
|
||||
throw new Error("Please select no more than 2 queries.");
|
||||
}
|
||||
|
||||
// Otherwise, present a dialog so the user can choose the item they want to use.
|
||||
const comparableQueryLabels = this.treeDataProvider.allHistory
|
||||
.filter(this.isSuccessfulCompletedLocalQueryInfo)
|
||||
.filter(
|
||||
(otherItem) =>
|
||||
otherItem !== fromItem && otherItem.databaseName === dbName,
|
||||
)
|
||||
.map((item) => ({
|
||||
label: this.labelProvider.getLabel(item),
|
||||
description: item.databaseName,
|
||||
detail: item.completedQuery.message,
|
||||
query: item,
|
||||
}));
|
||||
const comparableQueryLabelsWithDefault = [
|
||||
{
|
||||
label: "Single run",
|
||||
description:
|
||||
"Look at the performance of this run, compared to a trivial baseline",
|
||||
detail: undefined,
|
||||
query: undefined,
|
||||
},
|
||||
...comparableQueryLabels,
|
||||
];
|
||||
if (comparableQueryLabelsWithDefault.length < 1) {
|
||||
throw new Error("No other queries available to compare with.");
|
||||
}
|
||||
const choice = await window.showQuickPick(comparableQueryLabelsWithDefault);
|
||||
|
||||
return choice?.query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the compare with source query. This ensures that all compare command invocations
|
||||
* when exactly 2 queries are selected always have the proper _from_ query. Always use
|
||||
|
||||
Reference in New Issue
Block a user