Skip to content

Commit 8958297

Browse files
committed
fix: optimize WUDetails call
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent 68feefd commit 8958297

3 files changed

Lines changed: 98 additions & 71 deletions

File tree

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/comms/src/ecl/query.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,31 +172,43 @@ export class Query extends StateObject<QueryEx, QueryEx> implements QueryEx {
172172
const meta = promises[1];
173173
const metrics: WsWorkunits.Scope[] = promises[2];
174174
const data = metrics.map(metric => {
175-
if (metric.Id[0] === "a" || metric.Id[0] === "e") {
175+
const firstChar = metric.Id[0];
176+
if (firstChar === "a" || firstChar === "e") {
176177
const item = graph.idx[metric.Id.substring(1)];
178+
if (!item) return metric;
179+
const existingProperties = new Set(
180+
metric.Properties.Property.map(prop => prop.Name)
181+
);
182+
const newProperties: WsWorkunits.Property[] = [];
177183
for (const key in item) {
178-
if (key.charAt(0) !== "_" && key.charAt(0) === key.charAt(0).toUpperCase() && (typeof item[key] === "string" || typeof item[key] === "number" || typeof item[key] === "boolean")) {
179-
180-
if (!metric.Properties.Property.some(row => row.Name === key)) {
181-
const isNum = isNumber(item[key]);
182-
let rawValue = isNum ? parseFloat(item[key] as string) : item[key];
183-
let formatted = item[key];
184-
if (key.indexOf("Time") >= 0) {
185-
rawValue = rawValue as number / 1000000000;
184+
const firstCharOfKey = key.charAt(0);
185+
if (firstCharOfKey !== "_" &&
186+
firstCharOfKey === firstCharOfKey.toUpperCase() &&
187+
!existingProperties.has(key)) {
188+
const value = item[key];
189+
const valueType = typeof value;
190+
if (valueType === "string" || valueType === "number" || valueType === "boolean") {
191+
const isNum = isNumber(value);
192+
let rawValue = isNum ? parseFloat(value as string) : value;
193+
let formatted = value;
194+
if (key.includes("Time")) {
195+
rawValue = (rawValue as number) / 1000000000;
186196
formatted = siFormatter(rawValue) + "s";
187197
}
188-
metric.Properties.Property.push({
198+
newProperties.push({
189199
Name: key,
190200
RawValue: rawValue as any,
191201
Formatted: formatted
192202
} as WsWorkunits.Property);
193203
}
194204
}
195205
}
206+
if (newProperties.length > 0) {
207+
metric.Properties.Property.push(...newProperties);
208+
}
196209
}
197210
return metric;
198211
});
199-
200212
return wu.normalizeDetails(meta, data);
201213
});
202214
}

packages/comms/src/ecl/workunit.ts

Lines changed: 74 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -665,60 +665,62 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
665665

666666
normalizeDetails(meta: WsWorkunits.WUDetailsMetaResponse, scopes: WsWorkunits.Scope[]): { meta: WsWorkunits.WUDetailsMetaResponse, columns: { [id: string]: any }, data: IScope[] } {
667667
const columns: { [id: string]: any } = {
668-
id: {
669-
Measure: "label"
670-
},
671-
name: {
672-
Measure: "label"
673-
},
674-
type: {
675-
Measure: "label"
676-
}
668+
id: { Measure: "label" },
669+
name: { Measure: "label" },
670+
type: { Measure: "label" }
677671
};
678-
const data: IScope[] = [];
679-
for (const scope of scopes) {
680-
const props = {};
681-
const formattedProps = {};
682-
if (scope && scope.Id && scope.Properties && scope.Properties.Property) {
683-
for (const key in scope.Properties.Property) {
684-
const scopeProperty = scope.Properties.Property[key];
685-
if (scopeProperty.Measure === "ns") {
672+
const activityMap = new Map<number, string>();
673+
if (meta.Activities?.Activity) {
674+
for (const activity of meta.Activities.Activity) {
675+
activityMap.set(activity.Kind, activity.Name);
676+
}
677+
}
678+
const data: IScope[] = new Array(scopes.length);
679+
for (let i = 0; i < scopes.length; i++) {
680+
const scope = scopes[i];
681+
const props: { [key: string]: any } = {};
682+
const formattedProps: { [key: string]: any } = {};
683+
if (scope?.Id && scope.Properties?.Property) {
684+
const properties = scope.Properties.Property;
685+
const propertyCount = properties.length;
686+
for (let j = 0; j < propertyCount; j++) {
687+
const scopeProperty = properties[j];
688+
const measure = scopeProperty.Measure;
689+
const name = scopeProperty.Name;
690+
const rawValue = scopeProperty.RawValue;
691+
if (measure === "ns") {
686692
scopeProperty.Measure = "s";
687693
}
688-
if (scopeProperty.Name === "Kind") {
689-
const rawValue = parseInt(scopeProperty.RawValue, 10);
690-
scopeProperty.Formatted = meta.Activities.Activity.filter(a => a.Kind === rawValue)[0].Name ?? scopeProperty.RawValue;
694+
if (name === "Kind") {
695+
const rawValueInt = parseInt(rawValue, 10);
696+
scopeProperty.Formatted = activityMap.get(rawValueInt) ?? rawValue;
691697
}
692-
columns[scopeProperty.Name] = { ...scopeProperty };
693-
safeDelete(columns, scopeProperty.Name, "RawValue");
694-
safeDelete(columns, scopeProperty.Name, "Formatted");
695-
switch (scopeProperty.Measure) {
698+
columns[name] = {
699+
Name: scopeProperty.Name,
700+
Measure: scopeProperty.Measure,
701+
Creator: scopeProperty.Creator,
702+
CreatorType: scopeProperty.CreatorType
703+
};
704+
const numericRawValue = +rawValue;
705+
switch (measure === "ns" ? "s" : measure) {
696706
case "bool":
697-
props[scopeProperty.Name] = !!+scopeProperty.RawValue;
707+
props[name] = !!numericRawValue;
698708
break;
699709
case "sz":
700-
props[scopeProperty.Name] = +scopeProperty.RawValue;
710+
case "cnt":
711+
case "node":
712+
case "skw":
713+
case "ns":
714+
props[name] = numericRawValue;
701715
break;
702716
case "s":
703-
props[scopeProperty.Name] = +scopeProperty.RawValue / 1000000000;
704-
break;
705-
case "ns":
706-
props[scopeProperty.Name] = +scopeProperty.RawValue;
717+
props[name] = numericRawValue / 1000000000;
707718
break;
708719
case "ts":
709-
props[scopeProperty.Name] = new Date(+scopeProperty.RawValue / 1000).toISOString();
710-
break;
711-
case "cnt":
712-
props[scopeProperty.Name] = +scopeProperty.RawValue;
720+
props[name] = new Date(numericRawValue / 1000).toISOString();
713721
break;
714722
case "cost":
715-
props[scopeProperty.Name] = +scopeProperty.RawValue / 1000000;
716-
break;
717-
case "node":
718-
props[scopeProperty.Name] = +scopeProperty.RawValue;
719-
break;
720-
case "skw":
721-
props[scopeProperty.Name] = +scopeProperty.RawValue;
723+
props[name] = numericRawValue / 1000000;
722724
break;
723725
case "cpu":
724726
case "ppm":
@@ -729,11 +731,10 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
729731
case "id":
730732
case "fname":
731733
default:
732-
props[scopeProperty.Name] = scopeProperty.RawValue;
734+
props[name] = rawValue;
733735
}
734-
formattedProps[scopeProperty.Name] = formatNum(scopeProperty.Formatted ?? props[scopeProperty.Name]);
736+
formattedProps[name] = formatNum(scopeProperty.Formatted ?? props[name]);
735737
}
736-
// Other properties ---
737738
}
738739
const normalizedScope: IScope = {
739740
id: scope.Id,
@@ -748,38 +749,51 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
748749
__StdDevsSource: "",
749750
...props
750751
};
751-
if (normalizedScope[DEFINITION_LIST]) {
752+
const definitionList = normalizedScope[DEFINITION_LIST];
753+
if (definitionList) {
752754
try {
753-
const definitionList = JSON.parse(normalizedScope[DEFINITION_LIST].split("\\").join("\\\\"));
754-
normalizedScope[DEFINITION_LIST] = [];
755-
definitionList.forEach((definition, idx) => {
756-
const matches = definition.match(definitionRegex);
755+
const parsedList = JSON.parse(definitionList.split("\\").join("\\\\"));
756+
const processedDefinitions: Array<{ filePath: string, line: number, col: number }> = [];
757+
758+
for (let k = 0; k < parsedList.length; k++) {
759+
const matches = parsedList[k].match(definitionRegex);
757760
if (matches) {
758-
const filePath = (matches[1] ?? "") + matches[2] + matches[3];
759-
const line = parseInt(matches[5]);
760-
const col = parseInt(matches[6]);
761-
normalizedScope[DEFINITION_LIST].push({ filePath, line, col });
761+
processedDefinitions.push({
762+
filePath: (matches[1] ?? "") + matches[2] + matches[3],
763+
line: parseInt(matches[5], 10),
764+
col: parseInt(matches[6], 10)
765+
});
762766
}
763-
});
767+
}
768+
normalizedScope[DEFINITION_LIST] = processedDefinitions;
764769
} catch (e) {
765-
logger.error(`Unexpected "DefinitionList": ${normalizedScope[DEFINITION_LIST]}`);
770+
logger.error(`Unexpected "DefinitionList": ${definitionList}`);
766771
}
767772
}
773+
768774
const dedup: DedupProperties = {};
775+
let maxStdDevs = 0;
776+
let maxStdDevsSource = "";
777+
769778
for (const key in normalizedScope) {
770-
if (key.indexOf("__") !== 0) {
779+
if (!key.startsWith("__")) {
771780
const row = formatValues(normalizedScope, key, dedup);
772781
if (row) {
773782
normalizedScope.__groupedProps[row.Key] = row;
774-
if (!isNaN(row.StdDevs) && normalizedScope.__StdDevs < row.StdDevs) {
775-
normalizedScope.__StdDevs = row.StdDevs;
776-
normalizedScope.__StdDevsSource = row.Key;
783+
if (!isNaN(row.StdDevs!) && row.StdDevs! > maxStdDevs) {
784+
maxStdDevs = row.StdDevs!;
785+
maxStdDevsSource = row.Key;
777786
}
778787
}
779788
}
780789
}
781-
data.push(normalizedScope);
790+
791+
normalizedScope.__StdDevs = maxStdDevs;
792+
normalizedScope.__StdDevsSource = maxStdDevsSource;
793+
794+
data[i] = normalizedScope;
782795
}
796+
783797
return {
784798
meta,
785799
columns,

0 commit comments

Comments
 (0)