perf_hooks#PerformanceObserver TypeScript Examples

The following examples show how to use perf_hooks#PerformanceObserver. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From garment with MIT License 6 votes vote down vote up
performanceObserver = new PerformanceObserver(items => {
  const measures = items
    .getEntries()
    .map(({ name, duration }) => ({ name, duration }))
    .filter(config.filter);
  if (config.print) {
    printMeasures(measures);
  }
  allMeasures.push(...measures);
})
Example #2
Source File: stripeLinter.ts    From vscode-stripe with MIT License 6 votes vote down vote up
constructor(telemetry: Telemetry, git: Git) {
    this.telemetry = telemetry;
    this.git = git;

    this.perfObserver = new PerformanceObserver((items) => {
      items.getEntries().forEach((entry) => {
        this.telemetry.sendEvent('linter.perf.git-check-ignore-duration', entry.duration);
      });
    });
    this.perfObserver.observe({entryTypes: ['measure']});
  }
Example #3
Source File: Kernel.ts    From civet with MIT License 6 votes vote down vote up
function Initialze() {
  if (!_current) {
    _instance = require('civetkern').civetkern
    const c = config.getConfig(true)
    _current = config.getCurrentDB()
    try{
      const messageObs = new PerformanceObserver((items) => {
        const measurements = items.getEntriesByType('measure');
        measurements.forEach(measurement => {
          console.debug('performance', measurement.name, measurement.duration)
        })
      })
      messageObs.observe({ entryTypes: ['measure'] })

      _instance.init(c, _flag, _enableLog)
    } catch(err) {
      console.error('config is', c)
      console.error(err)
    }
  }
  // console.info('_instance', _instance)
}
Example #4
Source File: perf.ts    From elderjs with MIT License 5 votes vote down vote up
perf = (page: Page | Elder, force = false) => {
  if (page.settings.debug.performance || force) {
    let obs = new PerformanceObserver((items) => {
      items.getEntries().forEach((entry) => {
        if (entry.name.includes(page.uid)) {
          page.perf.timings.push({ name: entry.name.replace(`-${page.uid}`, ''), duration: entry.duration });
          performance.clearMarks(entry.name);
        }
      });
    });

    // eslint-disable-next-line no-param-reassign
    page.perf = {
      timings: [],
      /**
       * Marks the performance timeline with {label}-start.
       *
       * @param {String} label
       */
      start: (label: string) => {
        performance.mark(`${label}-start-${page.uid}`);
      },
      /**
       * Marks the performance timeline with {label}-stop
       * It then records triggers a recording of the measurement.
       * @param {*} label
       */
      end: (label) => {
        performance.mark(`${label}-end-${page.uid}`);
        performance.measure(`${label}-${page.uid}`, `${label}-start-${page.uid}`, `${label}-end-${page.uid}`);
      },
      stop: () => {
        if (obs) obs.disconnect();
        obs = null;
      },
    };

    obs.observe({ entryTypes: ['measure'] });
  } else {
    const placeholder = () => {};
    // eslint-disable-next-line no-param-reassign
    page.perf = {
      timings: [],
      start: placeholder,
      end: placeholder,
      stop: placeholder,
    };
  }

  // eslint-disable-next-line no-param-reassign
  page.perf.prefix = (pre) => {
    return { start: (name) => page.perf.start(`${pre}.${name}`), end: (name) => page.perf.end(`${pre}.${name}`) };
  };
}
Example #5
Source File: measureLanguageServiceWorker.ts    From DefinitelyTyped-tools with MIT License 5 votes vote down vote up
async function measureLanguageService(
  languageService: LanguageService,
  args: MeasureLanguageServiceArgs
): Promise<LanguageServiceSingleMeasurement> {
  return {
    fileName: args.fileName,
    start: args.start,
    ...(await measureAtPosition(args.fileName, args.start)),
  };

  async function measureAtPosition(
    fileName: string,
    position: number
  ): Promise<Pick<LanguageServiceSingleMeasurement, "quickInfoDuration" | "completionsDuration">> {
    let quickInfoDuration = NaN;
    let completionsDuration = NaN;
    const observer = new PerformanceObserver((list) => {
      const completionsMeasurement = list.getEntriesByName("completionsMeasurement")[0];
      const quickInfoMeasurement = list.getEntriesByName("quickInfoMeasurement")[0];
      if (completionsMeasurement) {
        completionsDuration = completionsMeasurement.duration;
      }
      if (quickInfoMeasurement) {
        quickInfoDuration = quickInfoMeasurement.duration;
      }
    });

    observer.observe({ entryTypes: ["measure"] });
    getCompletionsAtPosition(languageService, fileName, position);
    getQuickInfoAtPosition(languageService, fileName, position);
    // Node 16 changed the PerformanceObserver callback to happen async,
    // so we have to sit here and wait for it...
    await new Promise((resolve) => setTimeout(resolve, 0));
    assert.ok(!isNaN(quickInfoDuration), "No measurement was recorded for quick info");
    assert.ok(!isNaN(completionsDuration), "No measurement was recorded for completions");
    observer.disconnect();

    return {
      quickInfoDuration,
      completionsDuration,
    };
  }
}
Example #6
Source File: stripeLinter.ts    From vscode-stripe with MIT License 5 votes vote down vote up
private perfObserver: PerformanceObserver;
Example #7
Source File: measurePerf.ts    From DefinitelyTyped-tools with MIT License 4 votes vote down vote up
export async function measurePerf({
  packageName,
  packageVersion,
  typeScriptVersion,
  definitelyTypedRootPath,
  allPackages,
  maxRunSeconds = Infinity,
  progress,
  nProcesses,
  iterations,
  tsPath,
  ts,
  batchRunStart,
  failOnErrors,
}: MeasurePerfOptions) {
  let duration = NaN;
  const sourceVersion = execSync("git rev-parse HEAD", { cwd: definitelyTypedRootPath, encoding: "utf8" }).trim();
  const observer = new PerformanceObserver((list) => {
    const totalMeasurement = list.getEntriesByName("benchmark")[0];
    duration = totalMeasurement.duration;
  });

  observer.observe({ entryTypes: ["measure"] });
  performance.mark("benchmarkStart");
  const typesPath = path.join(definitelyTypedRootPath, "types");

  const typings = allPackages.getTypingsData({
    name: packageName,
    version: packageVersion,
  });
  const packagePath = path.join(typesPath, typings.subDirectoryPath);
  const typesVersion = getLatestTypesVersionForTypeScriptVersion(typings.typesVersions, typeScriptVersion);
  const latestTSTypesDir = path.resolve(packagePath, typesVersion ? `ts${typesVersion}` : ".");
  await installDependencies(allPackages, typings.id, typesPath);

  const commandLine = getParsedCommandLineForPackage(ts, latestTSTypesDir);
  const testPaths = getTestFileNames(commandLine.fileNames);

  let done = 0;
  let lastUpdate = Date.now();
  let languageServiceCrashed = false;
  const testMatrix = createLanguageServiceTestMatrix(testPaths, latestTSTypesDir, commandLine.options, iterations);
  if (progress) {
    updateProgress(
      `${toPackageKey(packageName, packageVersion)}: benchmarking over ${nProcesses} processes`,
      0,
      testMatrix.inputs.length
    );
  }

  await runWithListeningChildProcesses({
    inputs: testMatrix.inputs,
    commandLineArgs: [],
    workerFile: measureLanguageServiceWorkerFilename,
    nProcesses,
    crashRecovery: !failOnErrors,
    cwd: process.cwd(),
    softTimeoutMs: maxRunSeconds * 1000,
    handleCrash: (input) => {
      languageServiceCrashed = true;
      console.error("Failed measurement on request:", JSON.stringify(input, undefined, 2));
    },
    handleOutput: (measurement: LanguageServiceSingleMeasurement) => {
      testMatrix.addMeasurement(measurement);
      done++;
      if (progress) {
        updateProgress(
          `${toPackageKey(packageName, packageVersion)}: benchmarking over ${nProcesses} processes`,
          done,
          testMatrix.inputs.length
        );
      } else if (Date.now() - lastUpdate > 1000 * 60 * 5) {
        // Log every 5 minutes or so to make sure Pipelines doesn’t shut us down
        console.log(((100 * done) / testMatrix.inputs.length).toFixed(1) + "% done...");
        lastUpdate = Date.now();
      }
    },
  });

  if (progress && done !== testMatrix.inputs.length) {
    updateProgress(`${toPackageKey(packageName, packageVersion)}: timed out`, done, testMatrix.inputs.length);
    process.stdout.write(os.EOL);
  }

  const batchCompilationInput: MeasureBatchCompilationChildProcessArgs = {
    tsPath,
    fileNames: commandLine.fileNames,
    options: commandLine.options,
  };

  let batchCompilationResult: MeasureBatchCompilationChildProcessResult | undefined;
  await runWithChildProcesses({
    inputs: [batchCompilationInput],
    workerFile: measureBatchCompilationWorkerFilename,
    commandLineArgs: [],
    nProcesses: 1,
    handleOutput: (result: MeasureBatchCompilationChildProcessResult) => {
      batchCompilationResult = result;
    },
  });

  if (!batchCompilationResult) {
    throw new Error("Failed to get batch compilation metrics");
  }

  performance.mark("benchmarkEnd");
  performance.measure("benchmark", "benchmarkStart", "benchmarkEnd");

  const measurement: PackageBenchmark = {
    ...batchCompilationResult,
    benchmarkDuration: duration,
    sourceVersion,
    packageName,
    packageVersionMajor: packageVersion.major,
    packageVersionMinor: packageVersion.minor,
    typeScriptVersion,
    typeScriptVersionMajorMinor: ts.versionMajorMinor,
    languageServiceBenchmarks: testMatrix.getAllBenchmarks(),
    requestedLanguageServiceTestIterations: iterations,
    languageServiceCrashed,
    testIdentifierCount: testMatrix.uniquePositionCount,
    batchRunStart,
  };

  return measurement;

  function getIdentifiers(sourceFile: SourceFile) {
    const identifiers: Node[] = [];
    ts.forEachChild(sourceFile, function visit(node) {
      if (ts.isIdentifier(node)) {
        identifiers.push(node);
      } else {
        ts.forEachChild(node, visit);
      }
    });
    return identifiers;
  }

  function getTestFileNames(fileNames: readonly string[]) {
    return fileNames.filter((name) => {
      const ext = path.extname(name);
      return (ext === Extension.Ts || ext === Extension.Tsx) && !name.endsWith(Extension.Dts);
    });
  }

  function createLanguageServiceTestMatrix(
    testPaths: string[],
    packageDirectory: string,
    compilerOptions: CompilerOptions,
    iterations: number
  ) {
    const fileMap = new Map<string, Map<number, LanguageServiceBenchmark>>();
    const inputs: MeasureLanguageServiceChildProcessArgs[] = [];
    let uniquePositionCount = 0;
    for (const testPath of testPaths) {
      const positionMap = new Map<number, LanguageServiceBenchmark>();
      fileMap.set(testPath, positionMap);
      const sourceFile = ts.createSourceFile(
        testPath,
        ts.sys.readFile(testPath)!,
        compilerOptions.target || ts.ScriptTarget.Latest
      );
      // Reverse: more complex examples are usually near the end of test files,
      // so prioritize those.
      const identifiers = getIdentifiers(sourceFile).reverse();
      uniquePositionCount += identifiers.length;
      // Do the loops in this order so that a single child process doesn’t
      // run iterations of the same exact measurement back-to-back to avoid
      // v8 optimizing a significant chunk of the work away.
      for (let i = 0; i < iterations; i++) {
        for (const identifier of identifiers) {
          const start = identifier.getStart(sourceFile);
          if (i === 0) {
            const lineAndCharacter = ts.getLineAndCharacterOfPosition(sourceFile, start);
            const benchmark: LanguageServiceBenchmark = {
              fileName: path.relative(definitelyTypedRootPath, testPath),
              start,
              end: identifier.getEnd(),
              identifierText: identifier.getText(sourceFile),
              line: lineAndCharacter.line + 1,
              offset: lineAndCharacter.character + 1,
              completionsDurations: [],
              quickInfoDurations: [],
            };
            positionMap.set(start, benchmark);
          }
          inputs.push({
            fileName: testPath,
            start,
            packageDirectory,
            tsPath,
          });
        }
      }
    }
    return {
      inputs,
      uniquePositionCount,
      addMeasurement: (measurement: LanguageServiceSingleMeasurement) => {
        const benchmark = fileMap.get(measurement.fileName)!.get(measurement.start)!;
        benchmark.completionsDurations.push(measurement.completionsDuration);
        benchmark.quickInfoDurations.push(measurement.quickInfoDuration);
      },
      getAllBenchmarks: () => {
        return Array.prototype.concat
          .apply(
            [],
            Array.from(fileMap.values()).map((map) => Array.from(map.values()))
          )
          .filter(
            (benchmark: LanguageServiceBenchmark) =>
              benchmark.completionsDurations.length > 0 || benchmark.quickInfoDurations.length > 0
          );
      },
    };
  }
}