Skip to content
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

compute performance baseline in a webworker #172405

Merged
merged 2 commits into from Jan 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/vs/base/browser/defaultWorkerFactory.ts
Expand Up @@ -9,6 +9,13 @@ import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } fro

const ttPolicy = window.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });

export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Worker {
if (!blobUrl.startsWith('blob:')) {
throw new URIError('Not a blob-url: ' + blobUrl);
}
return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, options);
}

function getWorker(label: string): Worker | Promise<Worker> {
// Option for hosts to overwrite the worker script (used in the standalone editor)
if (globals.MonacoEnvironment) {
Expand Down
54 changes: 34 additions & 20 deletions src/vs/workbench/services/timer/browser/timerService.ts
Expand Up @@ -16,9 +16,9 @@ import { Barrier, timeout } from 'vs/base/common/async';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ViewContainerLocation } from 'vs/workbench/common/views';
import { StopWatch } from 'vs/base/common/stopwatch';
import { TelemetryTrustedValue } from 'vs/platform/telemetry/common/telemetryUtils';
import { isWeb } from 'vs/base/common/platform';
import { createBlobWorker } from 'vs/base/browser/defaultWorkerFactory';

/* __GDPR__FRAGMENT__
"IMemoryInfo" : {
Expand Down Expand Up @@ -518,28 +518,42 @@ export abstract class AbstractTimerService implements ITimerService {

// we use fibonacci numbers to have a performance baseline that indicates
// how slow/fast THIS machine actually is.
const sw = new StopWatch(true);
let tooSlow = false;
function fib(n: number): number {
if (tooSlow) {
return 0;
}
if (sw.elapsed() >= 1000) {
tooSlow = true;
}
if (n <= 2) {
return n;

const jsSrc = (function computeBaseline(this: WindowOrWorkerGlobalScope) {
// the following operation took ~16ms (one frame at 64FPS) to complete on my machine. We derive performance observations
// from that. We also bail if that took too long (>1s)
let tooSlow = false;
function fib(n: number): number {
if (tooSlow) {
return 0;
}
if (performance.now() - t1 >= 1000) {
tooSlow = true;
}
if (n <= 2) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
return fib(n - 1) + fib(n - 2);
}

// the following operation took ~16ms (one frame at 64FPS) to complete on my machine. We derive performance observations
// from that. We also bail if that took too long (>1s)
sw.reset();
fib(24);
const value = Math.round(sw.elapsed());
const t1 = performance.now();
fib(24);
const value = Math.round(performance.now() - t1);
postMessage({ value: tooSlow ? -1 : value });

}).toString();

const blob = new Blob([`${jsSrc};\ncomputeBaseline();`], { type: 'application/javascript' });
const blobUrl = URL.createObjectURL(blob);

const worker = createBlobWorker(blobUrl, { name: 'perfBaseline' });
return new Promise<number>(resolve => {
worker.onmessage = e => resolve(e.data.value);

return (tooSlow ? -1 : value);
}).finally(() => {
worker.terminate();
URL.revokeObjectURL(blobUrl);
});
});
}

Expand Down