Skip to content

Commit

Permalink
Merge pull request #350 from IPDSnelting/fix/comparison-performance
Browse files Browse the repository at this point in the history
Speed up comparison page
  • Loading branch information
Kha authored Aug 5, 2023
2 parents 83f4f35 + f1f4df2 commit e9bfe4e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
51 changes: 30 additions & 21 deletions frontend/src/components/comparison/RunComparisonTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import {
Run,
DimensionDifference,
Dimension,
RunResultSuccess,
DimensionDifference,
DimensionInterpretation,
MeasurementSuccess,
DimensionInterpretation
Run,
RunResultSuccess
} from '@/store/types'
import { Prop } from 'vue-property-decorator'
Expand Down Expand Up @@ -165,19 +165,36 @@ export default class RunComparisonTable extends Vue {
]
}
/**
* Cache the differences indexed by dimension as that is the main lookup direction in the item generation.
*/
get differencesPerDimension(): Map<string, DimensionDifference> {
const diffsPerDim: Map<string, DimensionDifference> = new Map()
for (const diff of this.differences) {
// We only have one measurement per dimension, so this index is safe and won't collide.
// Safety assertion if this ever changes
if (diffsPerDim.has(diff.dimension.toString())) {
throw new Error(
'Duplicated dimension detected: ' + diff.dimension.toString()
)
}
// We never partially modify the contents, ignore changes to them.
diffsPerDim.set(diff.dimension.toString(), Object.freeze(diff))
}
return diffsPerDim
}
private get items(): TableItem[] {
const allDimensions = this.getDimensionsForRun(this.first).concat(
this.getDimensionsForRun(this.second)
)
const uniqueDimensions: Dimension[] = []
const uniqueDimensions: Map<string, Dimension> = new Map()
allDimensions.forEach(dim => {
if (!uniqueDimensions.find(existing => existing.equals(dim))) {
uniqueDimensions.push(dim)
}
uniqueDimensions.set(dim.toString(), dim)
})
return uniqueDimensions.map(
return Array.from(uniqueDimensions.values()).map(
dimension =>
new TableItem(
dimension.benchmark,
Expand All @@ -201,29 +218,23 @@ export default class RunComparisonTable extends Vue {
}
private getDifference(dimension: Dimension): number | undefined {
const difference = this.differences.find(it =>
it.dimension.equals(dimension)
)
const difference = this.differencesPerDimension.get(dimension.toString())
if (difference) {
return difference.absDiff
}
return undefined
}
private getDifferencePercent(dimension: Dimension): number | undefined {
const difference = this.differences.find(it =>
it.dimension.equals(dimension)
)
const difference = this.differencesPerDimension.get(dimension.toString())
if (difference) {
return difference.relDiff
}
return undefined
}
private getStddevDiff(dimension: Dimension): number | undefined {
const difference = this.differences.find(it =>
it.dimension.equals(dimension)
)
const difference = this.differencesPerDimension.get(dimension.toString())
if (difference) {
return difference.stddevDiff
}
Expand All @@ -232,9 +243,7 @@ export default class RunComparisonTable extends Vue {
private getValue(run: Run, dimension: Dimension): number | undefined {
if (run.result instanceof RunResultSuccess) {
const relevantMeasurement = run.result.measurements.find(it =>
it.dimension.equals(dimension)
)
const relevantMeasurement = run.result.forDimension(dimension)
if (!relevantMeasurement) {
return undefined
}
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,33 @@ export class RunResultVelcomError {
}
export class RunResultSuccess {
readonly measurements: Measurement[]
perDimension?: Map<string, Measurement>

constructor(measurements: Measurement[]) {
this.measurements = measurements
}

/**
* Returns the measurement for a given dimension from a lazily-populated cache.
*
* @param dimension the dimension to look up the measurement for
*/
public forDimension(dimension: Dimension): Measurement | undefined {
if (this.perDimension === undefined) {
this.perDimension = new Map()
for (const measurement of this.measurements) {
// We only have one measurement per dimension, so this index is safe and won't collide.
// Freeze the object as we won't make fine-granular changes to it (we always re-fetch the whole run)
this.perDimension.set(
measurement.dimension.toString(),
Object.freeze(measurement)
)
}
}
return this.perDimension!.get(dimension.toString())
}
}

export type RunResult =
| RunResultScriptError
| RunResultVelcomError
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/views/RunComparison.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,15 @@ export default class RunComparisonView extends Vue {
private async fetchData() {
this.comparison = null
this.comparison = await vxm.commitDetailComparisonModule.fetchComparison({
first: this.first,
second: this.second,
hash1: this.hash1,
hash2: this.hash2
})
// We don't need reactivity on this object, we only swap it wholesale.
this.comparison = Object.freeze(
await vxm.commitDetailComparisonModule.fetchComparison({
first: this.first,
second: this.second,
hash1: this.hash1,
hash2: this.hash2
})
)
}
mounted(): void {
Expand Down

0 comments on commit e9bfe4e

Please sign in to comment.