-
-
Couldn't load subscription status.
- Fork 58
More efficient build process checker #489
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
base: master
Are you sure you want to change the base?
More efficient build process checker #489
Conversation
|
Hello, life is a bit busy, but I will check it. |
|
They released a new version for |
|
I believe you've got access - the 'allow edits by maintainers' box is checked. Presumably you'd like it rebased on your main branch? I can do that if it helps. I have bashed together this test script (sorry, I couldn't get the // Dependencies:
// "find-process": "^2.0.0",
// "@types/ps-list": "^6.0.0",
import psList from "ps-list";
import * as findProcess from "find-process";
interface Logger {
info(message: string): void;
exceptionS(error: any): void;
}
interface ProcessInfo {
pid: number;
name: string;
cmd?: string;
}
class RunResults {
method: string;
avg_time: number;
min_time: number;
max_time: number;
run_times: number[];
constructor(method: string, avg_time: number, min_time: number, max_time: number, run_times: number[]) {
this.method = method;
this.avg_time = avg_time;
this.min_time = min_time;
this.max_time = max_time;
this.run_times = run_times;
}
print(): void {
console.log("\n=== Results ===");
console.log(`${this.method} method:`);
console.log(` Average: ${this.avg_time.toFixed(2)}ms`);
console.log(` Min: ${this.min_time.toFixed(2)}ms`);
console.log(` Max: ${this.max_time.toFixed(2)}ms`);
}
}
class ProcessMonitor {
// https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers
private readonly _defaultPattern =
/(^|[/\\])(bazel|cmake|make|ninja|cl|c\+\+|ld|clang|clang\+\+|gcc|g\+\+|link|icc|armcc|armclang)(-[^/\\]+)?(\.exe)?$/;
private _log: Logger;
constructor(logger: Logger) {
this._log = logger;
}
async findprocess_method(
pattern: RegExp = this._defaultPattern
): Promise<ProcessInfo[]> {
// Note: find-process has incorrect type definition for RegExp handling
// See: https://github.com/yibn2008/find-process/compare/1.4.11...2.0.0#diff-81b33228621820bded04ffbd7d49375fc742662fde6b7111ddb10457ceef7ae9R11
const findFn = (findProcess as any).default.default;
const processes = (await findFn(
"name",
pattern as unknown as string
)) as ProcessInfo[];
if (processes.length > 0) {
this._log.info(
"Found running build related processes: " +
processes.map((x) => JSON.stringify(x, undefined, 0)).join(", ")
);
} else {
this._log.info("Not found running build related process");
}
return processes;
}
private async pslist_method(
pattern: RegExp = this._defaultPattern
): Promise<ProcessInfo[]> {
const allProcesses = await psList();
const processes = allProcesses.filter((proc: { name: string }) =>
pattern.test(proc.name)
);
if (processes.length > 0) {
this._log.info(
"Found running build related processes: " +
processes
.map((x: { name: string }) => JSON.stringify(x, undefined, 0))
.join(", ")
);
} else {
this._log.info("Not found running build related process");
}
return processes as ProcessInfo[];
}
async checkPerformance(
pattern: RegExp = this._defaultPattern,
iterations: number = 10,
fn: (pattern: RegExp) => Promise<ProcessInfo[]>,
name: string
): Promise<RunResults> {
console.log(`Running '${name}' ${iterations} times...`);
console.log(`Warmup run...`);
await fn(pattern).catch(() => {});
const times: number[] = [];
for (let i = 0; i < iterations; i++) {
const start = performance.now();
try {
await fn(pattern);
} catch (error) {}
const end = performance.now();
times.push(end - start);
}
// Calculate statistics
const avg_time = times.reduce((a, b) => a + b, 0) / times.length;
const min_time = Math.min(...times);
const max_time = Math.max(...times);
return new RunResults(name, avg_time, min_time, max_time, times);
}
// Performance comparison method
async comparePerformance(
pattern: RegExp = this._defaultPattern,
iterations: number = 10
): Promise<void> {
console.log(`Comparing performance over ${iterations} iterations...`);
const [fp, ps] = await Promise.allSettled([
this.checkPerformance(pattern, iterations, this.findprocess_method.bind(this), "find-process"),
this.checkPerformance(pattern, iterations, this.pslist_method.bind(this), "ps-list")
]).then(results => [
results[0].status === 'fulfilled' ? results[0].value : undefined,
results[1].status === 'fulfilled' ? results[1].value : undefined
]);
if (fp) fp.print();
if (ps) ps.print();
if (fp && ps) {
const faster = fp.avg_time < ps.avg_time ? "find-process" : "ps-list";
const speedup =
(Math.abs(fp.avg_time - ps.avg_time) /
Math.min(fp.avg_time, ps.avg_time)) *
100;
console.log(`\n${faster} is ${speedup.toFixed(1)}% faster on average`);
}
}
}
// Example usage
const logger: Logger = {
info: (message: string) => console.log(`[INFO] ${message}`),
exceptionS: (error: any) => console.error(`[ERROR] ${error}`),
};
const monitor = new ProcessMonitor(logger);
monitor.comparePerformance().catch(console.error);Which, on my machine gives something like this: |
|
haha maybe I should just use linux permanently- from WSL: |
…ent_buildProcessChecker
|
pls review and test it |
What this PR does / why we need it:
Replaces
find-processwithps-listand a regex match.All find-process is being used for is to check if a process which matches the given regex is running. We don't need any of the detailed information provided by it, like the PID, etc.
On Windows at least, this uses a bundled copy of fastlist, which seems to be a lot more efficient.
It also adds a flag to the
_refreshfunction to prevent multiple runs occurring at once. It may have too many flags. It solved the issue on my machine, anyway.Which issue(s) this PR fixes:
#488 waitForBuildProcess spawning multiple heavyweight Powershell instances on Windows.