Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit b2ad419

Browse files
committed
reimplement the logic in js file
1 parent e9a64f6 commit b2ad419

File tree

1 file changed

+102
-60
lines changed

1 file changed

+102
-60
lines changed

analyze.js

Lines changed: 102 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
#!/usr/bin/env node
22

33
const fs = require("fs");
4-
const { exec } = require("child_process");
4+
const { execSync } = require("child_process");
55
const path = require("path");
66

7-
// Helper functions
8-
const extractMetric = (file, metric) => {
9-
const content = fs.readFileSync(file, "utf-8");
10-
const regex = new RegExp(`${metric}\\s+(\\d+\\.?\\d*)`);
11-
const match = content.match(regex);
12-
return match ? parseFloat(match[1]) : null;
13-
};
7+
function extractMetric(file, metric) {
8+
try {
9+
const command = `grep "${metric}" "${file}" | awk '{print $2}' | sed 's/ms//'`;
10+
const result = execSync(command, { encoding: "utf-8" }).trim();
11+
return result;
12+
} catch (error) {
13+
console.error(`Error extracting metric from ${file}: ${error.message}`);
14+
return null;
15+
}
16+
}
1417

15-
const average = (values) =>
16-
values.reduce((sum, value) => sum + value, 0) / values.length;
18+
function average(values) {
19+
const sum = values.reduce((a, b) => parseFloat(a) + parseFloat(b), 0);
20+
return sum / values.length;
21+
}
1722

1823
const formattedServerNames = {
1924
tailcall: "Tailcall",
@@ -40,14 +45,16 @@ const resultFiles = process.argv.slice(2);
4045
const avgReqSecs = {};
4146
const avgLatencies = {};
4247

43-
// Extract metrics and calculate averages
4448
servers.forEach((server, idx) => {
49+
const startIdx = idx * 3;
4550
const reqSecVals = [];
4651
const latencyVals = [];
4752
for (let j = 0; j < 3; j++) {
48-
const fileIdx = idx * 3 + j;
49-
reqSecVals.push(extractMetric(resultFiles[fileIdx], "Requests/sec"));
50-
latencyVals.push(extractMetric(resultFiles[fileIdx], "Latency"));
53+
const fileIdx = startIdx + j;
54+
const reqSec = extractMetric(resultFiles[fileIdx], "Requests/sec");
55+
const latency = extractMetric(resultFiles[fileIdx], "Latency");
56+
if (reqSec !== null) reqSecVals.push(reqSec);
57+
if (latency !== null) latencyVals.push(latency);
5158
}
5259
avgReqSecs[server] = average(reqSecVals);
5360
avgLatencies[server] = average(latencyVals);
@@ -57,24 +64,17 @@ servers.forEach((server, idx) => {
5764
const reqSecData = "/tmp/reqSec.dat";
5865
const latencyData = "/tmp/latency.dat";
5966

60-
const writeDataFile = (filePath, data) => {
61-
const content = [
62-
"Server Value",
63-
...data.map(({ server, value }) => `${server} ${value}`),
64-
].join("\n");
65-
fs.writeFileSync(filePath, content);
66-
};
67-
68-
writeDataFile(
67+
fs.writeFileSync(
6968
reqSecData,
70-
servers.map((server) => ({ server, value: avgReqSecs[server] }))
69+
"Server Value\n" +
70+
servers.map((server) => `${server} ${avgReqSecs[server]}`).join("\n")
7171
);
72-
writeDataFile(
72+
fs.writeFileSync(
7373
latencyData,
74-
servers.map((server) => ({ server, value: avgLatencies[server] }))
74+
"Server Value\n" +
75+
servers.map((server) => `${server} ${avgLatencies[server]}`).join("\n")
7576
);
7677

77-
// Determine which benchmark to use
7878
let whichBench = 1;
7979
if (resultFiles[0].startsWith("bench2")) {
8080
whichBench = 2;
@@ -85,37 +85,68 @@ if (resultFiles[0].startsWith("bench2")) {
8585
const reqSecHistogramFile = `req_sec_histogram${whichBench}.png`;
8686
const latencyHistogramFile = `latency_histogram${whichBench}.png`;
8787

88-
// Plotting using gnuplot
89-
const plotWithGnuplot = (outputFile, title, dataFile) => {
90-
const script = `
91-
set term pngcairo size 1280,720 enhanced font "Courier,12"
92-
set output "${outputFile}"
93-
set style data histograms
94-
set style histogram cluster gap 1
95-
set style fill solid border -1
96-
set xtics rotate by -45
97-
set boxwidth 0.9
98-
set title "${title}"
99-
stats "${dataFile}" using 2 nooutput
100-
set yrange [0:STATS_max*1.2]
101-
set key outside right top
102-
plot "${dataFile}" using 2:xtic(1) title "${title.split(" ")[0]}"
103-
`;
104-
exec(`gnuplot -e '${script}'`);
105-
};
88+
function getMaxValue(data) {
89+
return Math.max(
90+
...data
91+
.split("\n")
92+
.slice(1)
93+
.map((line) => parseFloat(line.split(" ")[1]))
94+
);
95+
}
10696

107-
plotWithGnuplot(reqSecHistogramFile, "Requests/Sec", reqSecData);
108-
plotWithGnuplot(latencyHistogramFile, "Latency (in ms)", latencyData);
97+
const reqSecMax = getMaxValue(fs.readFileSync(reqSecData, "utf-8")) * 1.2;
98+
const latencyMax = getMaxValue(fs.readFileSync(latencyData, "utf-8")) * 1.2;
99+
100+
const gnuplotScript = `
101+
set term pngcairo size 1280,720 enhanced font 'Courier,12'
102+
set output '${reqSecHistogramFile}'
103+
set style data histograms
104+
set style histogram cluster gap 1
105+
set style fill solid border -1
106+
set xtics rotate by -45
107+
set boxwidth 0.9
108+
set title 'Requests/Sec'
109+
set yrange [0:${reqSecMax}]
110+
set key outside right top
111+
plot '${reqSecData}' using 2:xtic(1) title 'Req/Sec'
112+
set output '${latencyHistogramFile}'
113+
set title 'Latency (in ms)'
114+
set yrange [0:${latencyMax}]
115+
plot '${latencyData}' using 2:xtic(1) title 'Latency'
116+
`;
117+
118+
const gnuplotScriptFile = "/tmp/gnuplot_script.gp";
119+
fs.writeFileSync(gnuplotScriptFile, gnuplotScript);
120+
121+
try {
122+
execSync(`gnuplot ${gnuplotScriptFile}`, { stdio: "inherit" });
123+
console.log("Gnuplot executed successfully");
124+
} catch (error) {
125+
console.error("Error executing gnuplot:", error.message);
126+
process.exit(1);
127+
}
109128

110-
// Move PNGs to assets
111129
const assetsDir = path.join(__dirname, "assets");
112130
if (!fs.existsSync(assetsDir)) {
113131
fs.mkdirSync(assetsDir);
114132
}
115-
fs.renameSync(reqSecHistogramFile, path.join(assetsDir, reqSecHistogramFile));
116-
fs.renameSync(latencyHistogramFile, path.join(assetsDir, latencyHistogramFile));
117133

118-
// Calculate relative performance and build the results table
134+
function moveFile(source, destination) {
135+
try {
136+
if (fs.existsSync(source)) {
137+
fs.renameSync(source, destination);
138+
console.log(`Moved ${source} to ${destination}`);
139+
} else {
140+
console.log(`Source file ${source} does not exist`);
141+
}
142+
} catch (error) {
143+
console.error(`Error moving file ${source}: ${error.message}`);
144+
}
145+
}
146+
147+
moveFile(reqSecHistogramFile, path.join(assetsDir, reqSecHistogramFile));
148+
moveFile(latencyHistogramFile, path.join(assetsDir, latencyHistogramFile));
149+
119150
const serverRPS = {};
120151
servers.forEach((server) => {
121152
serverRPS[server] = avgReqSecs[server];
@@ -127,14 +158,28 @@ const sortedServers = Object.keys(serverRPS).sort(
127158
const lastServer = sortedServers[sortedServers.length - 1];
128159
const lastServerReqSecs = avgReqSecs[lastServer];
129160

161+
const resultsFile = "results.md";
162+
163+
if (
164+
!fs.existsSync(resultsFile) ||
165+
fs.readFileSync(resultsFile, "utf8").trim() === ""
166+
) {
167+
fs.writeFileSync(
168+
resultsFile,
169+
`<!-- PERFORMANCE_RESULTS_START -->
170+
| Query | Server | Requests/sec | Latency (ms) | Relative |
171+
|-------:|--------:|--------------:|--------------:|---------:|`
172+
);
173+
}
174+
130175
let resultsTable = "";
131176

132177
if (whichBench === 1) {
133-
resultsTable += `<!-- PERFORMANCE_RESULTS_START -->\n\n| Query | Server | Requests/sec | Latency (ms) | Relative |\n|-------:|--------:|--------------:|--------------:|---------:|\n| ${whichBench} | \`{ posts { id userId title user { id name email }}}\` |`;
178+
resultsTable += `\n| ${whichBench} | \`{ posts { id userId title user { id name email }}}\` |`;
134179
} else if (whichBench === 2) {
135-
resultsTable += `| ${whichBench} | \`{ posts { title }}\` |`;
180+
resultsTable += `\n| ${whichBench} | \`{ posts { title }}\` |`;
136181
} else if (whichBench === 3) {
137-
resultsTable += `| ${whichBench} | \`{ greet }\` |`;
182+
resultsTable += `\n| ${whichBench} | \`{ greet }\` |`;
138183
}
139184

140185
sortedServers.forEach((server) => {
@@ -153,14 +198,11 @@ sortedServers.forEach((server) => {
153198
resultsTable += `\n|| [${formattedServerNames[server]}] | \`${formattedReqSecs}\` | \`${formattedLatencies}\` | \`${relativePerformance}x\` |`;
154199
});
155200

156-
if (whichBench === 3) {
157-
resultsTable += `\n\n<!-- PERFORMANCE_RESULTS_END -->`;
158-
}
159-
160-
const resultsFile = "results.md";
161-
fs.writeFileSync(resultsFile, resultsTable);
201+
fs.appendFileSync(resultsFile, resultsTable);
162202

163203
if (whichBench === 3) {
204+
fs.appendFileSync(resultsFile, "\n\n<!-- PERFORMANCE_RESULTS_END -->");
205+
164206
const finalResults = fs
165207
.readFileSync(resultsFile, "utf-8")
166208
.replace(/(\r\n|\n|\r)/gm, "\\n");

0 commit comments

Comments
 (0)