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

How it works? #1

Open
romeerez opened this issue Dec 9, 2023 · 1 comment
Open

How it works? #1

romeerez opened this issue Dec 9, 2023 · 1 comment

Comments

@romeerez
Copy link

romeerez commented Dec 9, 2023

Hello!

I've made a library with the same purpose, and just found your library when was publishing mine.

The purpose is the same, but I guess it works in a completely different way.

My lib injects a function for benchmarking right into the TS compiler (source), and then it is called in a loop (source). This allows us to type-check the same piece of code a million times and to measure nothing besides the type-checking of this code itself.

Can this library be used in the same way?
If the piece of code is importing a heavy file, and the library type-checks this piece many times, will the time for the heavy file be included?

@webNeat
Copy link
Owner

webNeat commented Dec 10, 2023

Hello!

Here is a simplified version of the core function that measures the time of type-checking a code snippet:

import * as ts from 'typescript'

async function measure(filePath: string, code?: string) {
  // if no code is given, we read the content of the file
  if (!code) code = await readFile(filePath, 'utf-8')

  // we create a TS source file
  const sourceFile = ts.createSourceFile(filePath, code, ts.ScriptTarget.ES2015, true)
  // we create a host and mock the content of the file (so it doesn't have to read it from disk)
  const host = ts.createCompilerHost({})
  const getSourceFile = host.getSourceFile
  host.getSourceFile = (filename, languageVersion) => {
    if (filename === path) return sourceFile
    return getSourceFile(filename, languageVersion)
  }
  // we create the TS program
  const program = ts.createProgram([filePath], { noEmitOnError: true }, host)

  // we measure the time it takes to type-check the program
  const start = performance.now()
  const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile)
  return performance.now() - start
}

So if we are measuring a file or code snippet which doesn't import other files, we will not count the time it takes to read the file from disk.

But if the code imports other files, we count the time it takes to load those files from disk.

I am aware that this may not be the optimal way of doing it, and I am still investigating other ways to do a better job. In particular, I am exploring the tsc command line options to generate detailed reports and parse them to take to the information we need.

One of the goals of this library is to include a command line ts-pref:

$ ts-perf tests/**/*.bench.ts

tests/foo.bench.ts  124ms
tests/bar.bench.ts   241ms
...

This would be useful for generic types libraries like hotscript and my just-types library.

Does that answer your question?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants