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

Write path normalization without array allocations #60812

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

andrewbranch
Copy link
Member

@andrewbranch andrewbranch commented Dec 18, 2024

Related: #60633
Alternative to #60755

Despite the good benchmarks, I didn’t see any measurable impact in real-world updateGraphWorker duration on my M2 Mac Mini. However, since that was a GC hot spot for @dbaeumer and #60755 improved things some, this may do even better for him.

bench.js
const ts = require("./built/local/typescript");
const ts_old = require("./node_modules/typescript");
const { Suite } = require("bench-node");

const suite = new Suite();

suite.add("normalizePath_old", () => {
  runScenarios(ts_old.normalizePath);
});

suite.add("normalizePath_new", () => {
  runScenarios(ts.normalizePath);
});

suite.add("getNormalizedAbsolutePath_old", () => {
  runScenarios(ts_old.getNormalizedAbsolutePath);
});

suite.add("getNormalizedAbsolutePath_new", () => {
  runScenarios(ts.getNormalizedAbsolutePath);
});

suite.run();

function runScenarios(normalize) {
  normalize("/", "");
  normalize("/.", "");
  normalize("/./", "");
  normalize("/../", "");
  normalize("/a", "");
  normalize("/a/", "");
  normalize("/a/.", "");
  normalize("/a/foo.", "");
  normalize("/a/./", "");
  normalize("/a/./b", "");
  normalize("/a/./b/", "");
  normalize("/a/..", "");
  normalize("/a/../", "");
  normalize("/a/../", "");
  normalize("/a/../b", "");
  normalize("/a/../b/", "");
  normalize("/a/..", "");
  normalize("/a/..", "/");
  normalize("/a/..", "b/");
  normalize("/a/..", "/b");
  normalize("/a/.", "b");
  normalize("/a/.", ".");

  // Tests as above, but with backslashes.
  normalize("\\", "");
  normalize("\\.", "");
  normalize("\\.\\", "");
  normalize("\\..\\", "");
  normalize("\\a\\.\\", "");
  normalize("\\a\\.\\b", "");
  normalize("\\a\\.\\b\\", "");
  normalize("\\a\\..", "");
  normalize("\\a\\..\\", "");
  normalize("\\a\\..\\", "");
  normalize("\\a\\..\\b", "");
  normalize("\\a\\..\\b\\", "");
  normalize("\\a\\..", "");
  normalize("\\a\\..", "\\");
  normalize("\\a\\..", "b\\");
  normalize("\\a\\..", "\\b");
  normalize("\\a\\.", "b");
  normalize("\\a\\.", ".");

  // Relative paths on an empty currentDirectory.
  normalize("", "");
  normalize(".", "");
  normalize("./", "");
  normalize("./a", "");
  // Strangely, these do not normalize to the empty string.
  normalize("..", "");
  normalize("../", "");
  normalize("../..", "");
  normalize("../../", "");
  normalize("./..", "");
  normalize("../../a/..", "");

  // Interaction between relative paths and currentDirectory.
  normalize("", "/home");
  normalize(".", "/home");
  normalize("./", "/home");
  normalize("..", "/home");
  normalize("../", "/home");
  normalize("a", "b");
  normalize("a", "b/c");

  // Base names starting or ending with a dot do not affect normalization.
  normalize(".a", "");
  normalize("..a", "");
  normalize("a.", "");
  normalize("a..", "");

  normalize("/base/./.a", "");
  normalize("/base/../.a", "");
  normalize("/base/./..a", "");
  normalize("/base/../..a", "");
  normalize("/base/./..a/b", "");
  normalize("/base/../..a/b", "");

  normalize("/base/./a.", "");
  normalize("/base/../a.", "");
  normalize("/base/./a..", "");
  normalize("/base/../a..", "");
  normalize("/base/./a../b", "");
  normalize("/base/../a../b", "");

  // Consecutive intermediate slashes are normalized to a single slash.
  normalize("a//b", "");
  normalize("a///b", "");
  normalize("a/b//c", "");
  normalize("/a/b//c", "");
  normalize("//a/b//c", "");

  // Backslashes are converted to slashes,
  // and then consecutive intermediate slashes are normalized to a single slash
  normalize("a\\\\b", "");
  normalize("a\\\\\\b", "");
  normalize("a\\b\\\\c", "");
  normalize("\\a\\b\\\\c", "");
  normalize("\\\\a\\b\\\\c", "");

  // The same occurs for mixed slashes.
  normalize("a/\\b", "");
  normalize("a\\/b", "");
  normalize("a\\/\\b", "");
  normalize("a\\b//c", "");
  normalize("\\a\\b\\\\c", "");
  normalize("\\\\a\\b\\\\c", "");
}
npm i --no-save bench-node
npm run build
node --allow-natives-syntax bench.js   
                                              
normalizePath_old                             x 49,990 ops/sec (13 runs sampled) v8-never-optimize=true min..max=(19.15us...20.48us)
normalizePath_new                             x 125,800 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(7.80us...8.27us)
getNormalizedAbsolutePath_old                 x 55,493 ops/sec (12 runs sampled) v8-never-optimize=true min..max=(17.17us...18.45us)
getNormalizedAbsolutePath_new                 x 125,567 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(7.90us...8.03us)

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Dec 18, 2024
@andrewbranch
Copy link
Member Author

@typescript-bot perf test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 18, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
perf test this ✅ Started 👀 Results

@@ -624,27 +624,103 @@ export function getNormalizedPathComponents(path: string, currentDirectory: stri
}

/** @internal */
export function getNormalizedAbsolutePath(fileName: string, currentDirectory: string | undefined): string {
return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
export function getNormalizedAbsolutePath(path: string, currentDirectory: string | undefined): string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if currentDirectory is almost always normalized.

@typescript-bot
Copy link
Collaborator

@andrewbranch
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 34 34 ~ ~ ~ p=1.000 n=6
Symbols 62,363 62,363 ~ ~ ~ p=1.000 n=6
Types 50,395 50,395 ~ ~ ~ p=1.000 n=6
Memory used 195,362k (± 1.01%) 196,140k (± 0.73%) ~ 193,230k 196,885k p=0.230 n=6
Parse Time 1.59s (± 1.19%) 1.61s (± 1.01%) +0.02s (+ 1.47%) 1.60s 1.64s p=0.048 n=6
Bind Time 0.87s (± 1.62%) 0.86s (± 1.47%) ~ 0.85s 0.88s p=0.249 n=6
Check Time 11.73s (± 0.48%) 11.79s (± 0.56%) ~ 11.71s 11.87s p=0.261 n=6
Emit Time 3.46s (± 3.38%) 3.33s (± 2.58%) ~ 3.26s 3.50s p=0.063 n=6
Total Time 17.65s (± 0.66%) 17.60s (± 0.75%) ~ 17.45s 17.77s p=0.471 n=6
angular-1 - node (v18.15.0, x64)
Errors 37 37 ~ ~ ~ p=1.000 n=6
Symbols 947,936 947,936 ~ ~ ~ p=1.000 n=6
Types 410,955 410,955 ~ ~ ~ p=1.000 n=6
Memory used 1,226,014k (± 0.00%) 1,225,733k (± 0.00%) -281k (- 0.02%) 1,225,632k 1,225,785k p=0.005 n=6
Parse Time 8.01s (± 0.80%) 8.21s (± 0.87%) +0.19s (+ 2.41%) 8.11s 8.27s p=0.006 n=6
Bind Time 2.29s (± 1.01%) 2.30s (± 0.45%) ~ 2.28s 2.31s p=0.220 n=6
Check Time 38.28s (± 0.44%) 38.60s (± 0.41%) +0.32s (+ 0.84%) 38.38s 38.82s p=0.013 n=6
Emit Time 18.34s (± 0.77%) 19.85s (± 0.82%) 🔻+1.51s (+ 8.24%) 19.70s 20.14s p=0.005 n=6
Total Time 66.92s (± 0.44%) 68.96s (± 0.29%) +2.04s (+ 3.05%) 68.72s 69.22s p=0.005 n=6
mui-docs - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,449,172 2,449,172 ~ ~ ~ p=1.000 n=6
Types 896,410 896,410 ~ ~ ~ p=1.000 n=6
Memory used 2,321,055k (± 0.00%) 2,320,238k (± 0.01%) -817k (- 0.04%) 2,319,979k 2,320,359k p=0.005 n=6
Parse Time 11.39s (± 0.39%) 11.77s (± 1.44%) +0.38s (+ 3.31%) 11.66s 12.11s p=0.005 n=6
Bind Time 2.68s (± 0.28%) 2.66s (± 0.97%) ~ 2.62s 2.70s p=0.118 n=6
Check Time 88.08s (± 0.61%) 90.77s (± 1.75%) +2.69s (+ 3.06%) 88.98s 93.25s p=0.005 n=6
Emit Time 0.35s (± 4.04%) 0.36s (± 2.84%) ~ 0.35s 0.38s p=0.118 n=6
Total Time 102.50s (± 0.51%) 105.56s (± 1.45%) +3.06s (+ 2.99%) 103.84s 108.01s p=0.005 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,226,880 1,226,894 +14 (+ 0.00%) ~ ~ p=0.001 n=6
Types 266,745 266,772 +27 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,846,394k (±13.21%) 2,847,042k (±13.14%) ~ 2,363,411k 3,089,147k p=0.689 n=6
Parse Time 6.75s (± 2.20%) 6.76s (± 1.67%) ~ 6.61s 6.89s p=1.000 n=6
Bind Time 2.16s (± 2.08%) 2.18s (± 1.77%) ~ 2.12s 2.23s p=0.810 n=6
Check Time 42.75s (± 0.52%) 42.96s (± 0.53%) ~ 42.64s 43.31s p=0.230 n=6
Emit Time 3.49s (± 3.25%) 3.46s (± 3.04%) ~ 3.31s 3.64s p=0.470 n=6
Total Time 55.15s (± 0.57%) 55.35s (± 0.58%) ~ 54.85s 55.82s p=0.297 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,226,880 1,226,894 +14 (+ 0.00%) ~ ~ p=0.001 n=6
Types 266,745 266,772 +27 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 3,032,595k (± 9.77%) 3,033,234k (± 9.76%) ~ 2,428,371k 3,155,346k p=0.378 n=6
Parse Time 8.65s (± 1.54%) 8.71s (± 1.29%) ~ 8.49s 8.79s p=0.093 n=6
Bind Time 2.65s (± 1.51%) 2.64s (± 1.19%) ~ 2.59s 2.68s p=0.810 n=6
Check Time 53.24s (± 0.37%) 53.40s (± 0.13%) ~ 53.31s 53.47s p=0.128 n=6
Emit Time 4.39s (± 2.24%) 4.32s (± 2.25%) ~ 4.20s 4.44s p=0.378 n=6
Total Time 68.93s (± 0.28%) 69.07s (± 0.14%) ~ 68.94s 69.21s p=0.172 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 262,439 262,453 +14 (+ 0.01%) ~ ~ p=0.001 n=6
Types 106,628 106,629 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 440,184k (± 0.01%) 440,500k (± 0.01%) +316k (+ 0.07%) 440,436k 440,550k p=0.005 n=6
Parse Time 3.52s (± 1.10%) 3.58s (± 0.82%) +0.06s (+ 1.66%) 3.55s 3.63s p=0.028 n=6
Bind Time 1.32s (± 0.83%) 1.32s (± 1.75%) ~ 1.29s 1.35s p=0.870 n=6
Check Time 18.90s (± 0.44%) 19.06s (± 0.27%) +0.15s (+ 0.82%) 18.97s 19.11s p=0.010 n=6
Emit Time 1.52s (± 0.69%) 1.53s (± 0.34%) ~ 1.53s 1.54s p=0.142 n=6
Total Time 25.26s (± 0.42%) 25.49s (± 0.24%) +0.22s (+ 0.89%) 25.38s 25.55s p=0.006 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 70 70 ~ ~ ~ p=1.000 n=6
Symbols 226,062 226,062 ~ ~ ~ p=1.000 n=6
Types 94,488 94,488 ~ ~ ~ p=1.000 n=6
Memory used 371,576k (± 0.02%) 371,654k (± 0.03%) ~ 371,558k 371,896k p=0.261 n=6
Parse Time 2.91s (± 0.77%) 2.91s (± 1.20%) ~ 2.86s 2.95s p=0.517 n=6
Bind Time 1.58s (± 0.84%) 1.59s (± 1.92%) ~ 1.55s 1.63s p=0.464 n=6
Check Time 16.54s (± 0.54%) 16.53s (± 0.32%) ~ 16.45s 16.61s p=0.936 n=6
Emit Time 0.00s (±244.70%) 0.00s ~ ~ ~ p=0.405 n=6
Total Time 21.03s (± 0.38%) 21.04s (± 0.41%) ~ 20.91s 21.16s p=1.000 n=6
vscode - node (v18.15.0, x64)
Errors 3 3 ~ ~ ~ p=1.000 n=6
Symbols 3,222,386 3,222,386 ~ ~ ~ p=1.000 n=6
Types 1,108,493 1,108,493 ~ ~ ~ p=1.000 n=6
Memory used 3,288,091k (± 0.01%) 3,287,870k (± 0.01%) ~ 3,287,518k 3,288,482k p=0.298 n=6
Parse Time 14.21s (± 0.33%) 14.80s (± 2.89%) 🔻+0.60s (+ 4.21%) 14.49s 15.66s p=0.005 n=6
Bind Time 4.53s (± 0.57%) 4.62s (± 2.79%) ~ 4.52s 4.81s p=0.225 n=6
Check Time 88.99s (± 3.43%) 90.52s (± 2.98%) ~ 89.09s 96.01s p=0.230 n=6
Emit Time 27.20s (± 7.39%) 31.85s (± 6.12%) 🔻+4.65s (+17.09%) 27.93s 33.04s p=0.013 n=6
Total Time 134.93s (± 2.20%) 141.81s (± 0.69%) 🔻+6.88s (+ 5.10%) 140.77s 143.06s p=0.005 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 291,468 291,468 ~ ~ ~ p=1.000 n=6
Types 118,921 118,921 ~ ~ ~ p=1.000 n=6
Memory used 445,188k (± 0.02%) 445,209k (± 0.03%) ~ 445,042k 445,409k p=0.810 n=6
Parse Time 4.04s (± 0.72%) 4.09s (± 1.05%) ~ 4.02s 4.14s p=0.091 n=6
Bind Time 1.76s (± 0.78%) 1.76s (± 0.86%) ~ 1.75s 1.79s p=1.000 n=6
Check Time 18.74s (± 0.48%) 18.76s (± 0.51%) ~ 18.66s 18.89s p=0.936 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 24.54s (± 0.41%) 24.62s (± 0.44%) ~ 24.52s 24.78s p=0.378 n=6
xstate-main - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 552,233 552,233 ~ ~ ~ p=1.000 n=6
Types 184,971 184,971 ~ ~ ~ p=1.000 n=6
Memory used 492,315k (± 0.02%) 492,202k (± 0.01%) -113k (- 0.02%) 492,163k 492,254k p=0.031 n=6
Parse Time 2.76s (± 0.15%) 2.80s (± 0.27%) +0.04s (+ 1.33%) 2.79s 2.81s p=0.003 n=6
Bind Time 0.96s 0.96s ~ ~ ~ p=1.000 n=6
Check Time 16.16s (± 0.27%) 16.20s (± 0.28%) ~ 16.16s 16.27s p=0.261 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 19.88s (± 0.21%) 19.97s (± 0.21%) +0.09s (+ 0.44%) 19.93s 20.03s p=0.006 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

tsserver

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-UnionsTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,312ms (± 0.59%) 2,342ms (± 0.35%) +30ms (+ 1.30%) 2,327ms 2,349ms p=0.005 n=6
Req 2 - geterr 5,287ms (± 0.30%) 5,332ms (± 0.22%) +45ms (+ 0.85%) 5,320ms 5,347ms p=0.005 n=6
Req 3 - references 263ms (± 1.58%) 267ms (± 1.56%) ~ 261ms 270ms p=0.076 n=6
Req 4 - navto 227ms (± 0.53%) 227ms (± 0.54%) ~ 226ms 229ms p=0.788 n=6
Req 5 - completionInfo count 1,357 1,357 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 77ms (± 3.88%) 81ms (± 9.55%) ~ 76ms 91ms p=0.208 n=6
CompilerTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,456ms (± 1.59%) 2,464ms (± 1.27%) ~ 2,420ms 2,499ms p=0.689 n=6
Req 2 - geterr 4,056ms (± 0.50%) 4,071ms (± 0.44%) ~ 4,053ms 4,093ms p=0.173 n=6
Req 3 - references 284ms (± 0.48%) 284ms (± 0.29%) ~ 283ms 285ms p=0.934 n=6
Req 4 - navto 228ms (± 0.18%) 228ms ~ ~ ~ p=0.405 n=6
Req 5 - completionInfo count 1,519 1,519 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 85ms (± 3.28%) 87ms (± 1.19%) ~ 86ms 88ms p=0.542 n=6
xstate-main-1-tsserver - node (v18.15.0, x64)
Req 1 - updateOpen 5,311ms (± 0.26%) 5,367ms (± 0.25%) +56ms (+ 1.06%) 5,350ms 5,384ms p=0.005 n=6
Req 2 - geterr 1,149ms (± 0.80%) 1,168ms (± 0.97%) +19ms (+ 1.67%) 1,155ms 1,183ms p=0.020 n=6
Req 3 - references 83ms 78ms (± 0.66%) 🟩-5ms (- 6.43%) 77ms 78ms p=0.002 n=6
Req 4 - navto 450ms (± 0.27%) 454ms (± 0.62%) +3ms (+ 0.74%) 451ms 458ms p=0.027 n=6
Req 5 - completionInfo count 3,450 3,450 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 853ms (± 1.86%) 838ms (± 1.19%) ~ 821ms 850ms p=0.199 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • CompilerTSServer - node (v18.15.0, x64)
  • Compiler-UnionsTSServer - node (v18.15.0, x64)
  • xstate-main-1-tsserver - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

startup

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
tsc-startup - node (v18.15.0, x64)
Execution time 161.64ms (± 0.22%) 161.69ms (± 0.18%) +0.06ms (+ 0.04%) 160.53ms 164.00ms p=0.005 n=600
tsserver-startup - node (v18.15.0, x64)
Execution time 233.15ms (± 0.15%) 235.26ms (± 0.85%) +2.12ms (+ 0.91%) 231.65ms 267.00ms p=0.000 n=600
tsserverlibrary-startup - node (v18.15.0, x64)
Execution time 232.11ms (± 0.15%) 231.93ms (± 0.16%) -0.18ms (- 0.08%) 230.45ms 238.24ms p=0.000 n=600
typescript-startup - node (v18.15.0, x64)
Execution time 227.99ms (± 0.19%) 227.82ms (± 0.16%) -0.17ms (- 0.08%) 226.47ms 232.88ms p=0.000 n=600
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • tsc-startup - node (v18.15.0, x64)
  • tsserver-startup - node (v18.15.0, x64)
  • tsserverlibrary-startup - node (v18.15.0, x64)
  • typescript-startup - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

Comment on lines 633 to 636
const root = path.substring(0, rootLength);
const normalizedRoot = root && normalizeSlashes(root);
// `normalized` is only initialized once `path` is determined to be non-normalized
let normalized = normalizedRoot === root ? undefined : normalizedRoot;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just use lastIndexOf to see if altDirectorySeparator occurs. That way you can avoid creating a substring for root at all.

@andrewbranch
Copy link
Member Author

I’m puzzled by the perf results

@andrewbranch
Copy link
Member Author

Changing the scenarios to have long paths that are already normalized shows the old normalizePath regex fast path to be the winner. The scenarios being benchmarked are the tests, which skew heavily toward needing normalization, whereas real-world usage usually results in a no-op. Probably using the regex to test, new function to modify, is going to be the best combination.

@andrewbranch andrewbranch changed the title Write path normalization without array allocations or regexes Write path normalization without array allocations Dec 19, 2024
@andrewbranch
Copy link
Member Author

@typescript-bot perf test

@typescript-bot
Copy link
Collaborator

typescript-bot commented Dec 19, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
perf test ✅ Started 👀 Results

Comment on lines 661 to 662
const sepIndex = path.indexOf(directorySeparator, index + 1);
const altSepIndex = path.indexOf(altDirectorySeparator, index + 1);
Copy link
Member

@DanielRosenwasser DanielRosenwasser Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quadratic because you have to find at least one of the other kinds of slashes over and over. You should just tight-loop on !isAnyDirectorySeparator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or use findIndex(path, isAnyDirectorySeparator, index + 1)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with findIndex is that it might not optimize well it passed in both arrays and strings. Maybe I'm superstitious.

// At beginning of segment
segmentStart = index;
let ch = path.charCodeAt(index);
while (isAnyDirectorySeparator(ch) && index + 1 < path.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me a bit to see why this works, but it's because index starts immediately after the root, or after the first separator following the prior segment. Figuring out if one of those is a backslash is handled below.

normalizedUpTo = index + 2;
}
}
else if (normalized === undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that in this branch it is technically possible for you to avoid extra substrings by adjusting normalizedUpTo instead of initializing normalized.

@typescript-bot
Copy link
Collaborator

@andrewbranch
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 34 34 ~ ~ ~ p=1.000 n=6
Symbols 62,363 62,363 ~ ~ ~ p=1.000 n=6
Types 50,395 50,395 ~ ~ ~ p=1.000 n=6
Memory used 195,042k (± 1.01%) 196,764k (± 0.09%) ~ 196,453k 196,962k p=0.298 n=6
Parse Time 1.61s (± 1.30%) 1.60s (± 1.84%) ~ 1.56s 1.64s p=0.373 n=6
Bind Time 0.88s (± 2.14%) 0.87s (± 0.60%) ~ 0.86s 0.87s p=0.452 n=6
Check Time 11.74s (± 0.14%) 11.76s (± 0.66%) ~ 11.67s 11.90s p=1.000 n=6
Emit Time 3.28s (± 1.20%) 3.31s (± 3.47%) ~ 3.24s 3.54s p=0.936 n=6
Total Time 17.50s (± 0.42%) 17.53s (± 0.61%) ~ 17.40s 17.66s p=0.687 n=6
angular-1 - node (v18.15.0, x64)
Errors 37 37 ~ ~ ~ p=1.000 n=6
Symbols 947,936 947,936 ~ ~ ~ p=1.000 n=6
Types 410,955 410,955 ~ ~ ~ p=1.000 n=6
Memory used 1,226,032k (± 0.00%) 1,225,726k (± 0.01%) -306k (- 0.02%) 1,225,636k 1,225,853k p=0.005 n=6
Parse Time 8.10s (± 0.81%) 8.05s (± 0.49%) ~ 8.02s 8.11s p=0.198 n=6
Bind Time 2.28s (± 0.95%) 2.29s (± 0.24%) ~ 2.29s 2.30s p=0.101 n=6
Check Time 38.17s (± 0.32%) 38.11s (± 0.36%) ~ 37.94s 38.31s p=0.423 n=6
Emit Time 18.36s (± 0.39%) 18.21s (± 0.22%) -0.15s (- 0.81%) 18.17s 18.29s p=0.008 n=6
Total Time 66.91s (± 0.24%) 66.67s (± 0.22%) ~ 66.48s 66.87s p=0.066 n=6
mui-docs - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,449,172 2,449,172 ~ ~ ~ p=1.000 n=6
Types 896,410 896,410 ~ ~ ~ p=1.000 n=6
Memory used 2,321,084k (± 0.00%) 2,320,392k (± 0.01%) -693k (- 0.03%) 2,320,197k 2,320,555k p=0.005 n=6
Parse Time 14.06s (± 0.95%) 13.92s (± 0.61%) -0.14s (- 1.00%) 13.76s 14.00s p=0.031 n=6
Bind Time 3.29s (± 0.51%) 3.29s (± 0.45%) ~ 3.27s 3.31s p=0.934 n=6
Check Time 108.54s (± 2.20%) 108.26s (± 1.40%) ~ 107.06s 110.72s p=0.688 n=6
Emit Time 0.43s (± 1.97%) 0.51s (±41.02%) ~ 0.41s 0.94s p=0.548 n=6
Total Time 126.31s (± 1.99%) 125.98s (± 1.24%) ~ 124.69s 128.19s p=0.575 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,226,880 1,226,898 +18 (+ 0.00%) ~ ~ p=0.001 n=6
Types 266,745 266,773 +28 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,967,103k (±10.01%) 2,725,331k (±14.65%) ~ 2,360,476k 3,091,267k p=0.689 n=6
Parse Time 6.81s (± 1.59%) 6.68s (± 1.40%) -0.12s (- 1.79%) 6.58s 6.79s p=0.031 n=6
Bind Time 2.16s (± 1.60%) 2.16s (± 1.70%) ~ 2.11s 2.19s p=0.872 n=6
Check Time 42.90s (± 0.20%) 42.78s (± 0.30%) ~ 42.53s 42.87s p=0.093 n=6
Emit Time 3.49s (± 2.72%) 3.48s (± 3.20%) ~ 3.37s 3.63s p=0.936 n=6
Total Time 55.35s (± 0.24%) 55.11s (± 0.42%) ~ 54.73s 55.39s p=0.066 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,226,880 1,226,898 +18 (+ 0.00%) ~ ~ p=0.001 n=6
Types 266,745 266,773 +28 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 3,032,854k (± 9.77%) 3,033,179k (± 9.74%) ~ 2,429,601k 3,154,501k p=1.000 n=6
Parse Time 6.98s (± 1.03%) 6.95s (± 0.81%) ~ 6.85s 7.00s p=0.297 n=6
Bind Time 2.17s (± 1.22%) 2.16s (± 1.21%) ~ 2.13s 2.19s p=0.517 n=6
Check Time 42.93s (± 0.45%) 42.77s (± 0.38%) ~ 42.52s 42.93s p=0.092 n=6
Emit Time 3.53s (± 6.37%) 3.52s (± 2.33%) ~ 3.39s 3.60s p=0.378 n=6
Total Time 55.61s (± 0.23%) 55.39s (± 0.46%) ~ 54.92s 55.63s p=0.065 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 262,439 262,457 +18 (+ 0.01%) ~ ~ p=0.001 n=6
Types 106,628 106,630 +2 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 440,209k (± 0.01%) 440,509k (± 0.02%) +300k (+ 0.07%) 440,407k 440,692k p=0.005 n=6
Parse Time 3.56s (± 0.61%) 3.54s (± 1.17%) ~ 3.51s 3.61s p=0.255 n=6
Bind Time 1.32s (± 0.92%) 1.32s (± 1.05%) ~ 1.30s 1.34s p=0.802 n=6
Check Time 18.90s (± 0.11%) 19.09s (± 0.92%) +0.19s (+ 0.98%) 18.95s 19.44s p=0.005 n=6
Emit Time 1.53s (± 0.76%) 1.54s (± 0.82%) ~ 1.53s 1.56s p=0.278 n=6
Total Time 25.31s (± 0.13%) 25.48s (± 0.84%) +0.17s (+ 0.68%) 25.28s 25.88s p=0.037 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 70 70 ~ ~ ~ p=1.000 n=6
Symbols 226,062 226,062 ~ ~ ~ p=1.000 n=6
Types 94,488 94,488 ~ ~ ~ p=1.000 n=6
Memory used 371,665k (± 0.03%) 371,718k (± 0.05%) ~ 371,533k 372,071k p=0.689 n=6
Parse Time 2.90s (± 0.72%) 2.88s (± 1.23%) ~ 2.83s 2.92s p=0.460 n=6
Bind Time 1.60s (± 1.25%) 1.58s (± 0.53%) ~ 1.57s 1.59s p=0.276 n=6
Check Time 16.47s (± 0.33%) 16.49s (± 0.27%) ~ 16.43s 16.56s p=0.423 n=6
Emit Time 0.00s (±244.70%) 0.00s ~ ~ ~ p=0.405 n=6
Total Time 20.97s (± 0.43%) 20.95s (± 0.33%) ~ 20.85s 21.05s p=0.936 n=6
vscode - node (v18.15.0, x64)
Errors 3 3 ~ ~ ~ p=1.000 n=6
Symbols 3,222,815 3,222,815 ~ ~ ~ p=1.000 n=6
Types 1,108,656 1,108,656 ~ ~ ~ p=1.000 n=6
Memory used 3,288,263k (± 0.01%) 3,288,265k (± 0.01%) ~ 3,287,962k 3,288,511k p=0.810 n=6
Parse Time 11.59s (± 0.17%) 11.52s (± 0.17%) -0.07s (- 0.62%) 11.50s 11.55s p=0.005 n=6
Bind Time 3.78s (± 0.72%) 3.85s (± 2.67%) ~ 3.75s 3.99s p=0.139 n=6
Check Time 73.69s (± 0.27%) 73.34s (± 0.14%) -0.35s (- 0.47%) 73.23s 73.50s p=0.016 n=6
Emit Time 23.75s (± 1.18%) 23.27s (± 0.63%) -0.47s (- 1.99%) 23.09s 23.44s p=0.005 n=6
Total Time 112.80s (± 0.39%) 111.98s (± 0.20%) -0.82s (- 0.73%) 111.70s 112.28s p=0.008 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 291,468 291,468 ~ ~ ~ p=1.000 n=6
Types 118,921 118,921 ~ ~ ~ p=1.000 n=6
Memory used 445,276k (± 0.03%) 445,259k (± 0.04%) ~ 444,963k 445,471k p=0.873 n=6
Parse Time 4.11s (± 0.40%) 4.10s (± 1.13%) ~ 4.04s 4.15s p=0.747 n=6
Bind Time 1.77s (± 1.36%) 1.77s (± 0.97%) ~ 1.74s 1.79s p=0.625 n=6
Check Time 18.78s (± 0.51%) 18.83s (± 0.60%) ~ 18.69s 18.97s p=0.470 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 24.68s (± 0.38%) 24.69s (± 0.52%) ~ 24.56s 24.84s p=1.000 n=6
xstate-main - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 552,233 552,233 ~ ~ ~ p=1.000 n=6
Types 184,971 184,971 ~ ~ ~ p=1.000 n=6
Memory used 492,390k (± 0.00%) 492,333k (± 0.01%) ~ 492,252k 492,398k p=0.128 n=6
Parse Time 3.40s (± 0.31%) 3.42s (± 0.57%) ~ 3.40s 3.45s p=0.119 n=6
Bind Time 1.17s (± 0.64%) 1.19s (± 1.89%) ~ 1.16s 1.21s p=0.216 n=6
Check Time 19.41s (± 0.26%) 19.44s (± 0.30%) ~ 19.38s 19.54s p=0.378 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 23.98s (± 0.23%) 24.05s (± 0.29%) ~ 23.97s 24.17s p=0.109 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

tsserver

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-UnionsTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,326ms (± 0.58%) 2,333ms (± 0.34%) ~ 2,326ms 2,345ms p=0.468 n=6
Req 2 - geterr 5,321ms (± 0.57%) 5,349ms (± 0.39%) ~ 5,320ms 5,383ms p=0.173 n=6
Req 3 - references 265ms (± 1.53%) 267ms (± 1.44%) ~ 263ms 270ms p=0.666 n=6
Req 4 - navto 227ms (± 0.46%) 228ms (± 0.58%) ~ 226ms 229ms p=0.116 n=6
Req 5 - completionInfo count 1,357 1,357 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 79ms (± 8.26%) 81ms (±10.15%) ~ 76ms 92ms p=0.652 n=6
CompilerTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,437ms (± 1.50%) 2,443ms (± 1.02%) ~ 2,399ms 2,467ms p=0.873 n=6
Req 2 - geterr 4,004ms (± 0.20%) 3,996ms (± 0.37%) ~ 3,976ms 4,017ms p=0.258 n=6
Req 3 - references 280ms (± 1.23%) 280ms (± 1.26%) ~ 273ms 282ms p=0.623 n=6
Req 4 - navto 227ms (± 0.18%) 227ms (± 0.18%) ~ 226ms 227ms p=1.000 n=6
Req 5 - completionInfo count 1,519 1,519 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 83ms (± 5.12%) 83ms (± 5.08%) ~ 75ms 86ms p=0.517 n=6
xstate-main-1-tsserver - node (v18.15.0, x64)
Req 1 - updateOpen 5,314ms (± 0.18%) 5,319ms (± 0.79%) ~ 5,277ms 5,400ms p=0.630 n=6
Req 2 - geterr 1,150ms (± 0.81%) 1,156ms (± 0.64%) ~ 1,146ms 1,167ms p=0.295 n=6
Req 3 - references 83ms 76ms 🟩-7ms (- 8.43%) ~ ~ p=0.001 n=6
Req 4 - navto 452ms (± 1.07%) 450ms (± 0.33%) ~ 448ms 452ms p=0.568 n=6
Req 5 - completionInfo count 3,450 3,450 ~ ~ ~ p=1.000 n=6
Req 5 - completionInfo 855ms (± 1.39%) 849ms (± 1.08%) ~ 834ms 861ms p=0.421 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • CompilerTSServer - node (v18.15.0, x64)
  • Compiler-UnionsTSServer - node (v18.15.0, x64)
  • xstate-main-1-tsserver - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

startup

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
tsc-startup - node (v18.15.0, x64)
Execution time 158.93ms (± 0.21%) 158.98ms (± 0.20%) ~ 157.74ms 162.13ms p=0.086 n=600
tsserver-startup - node (v18.15.0, x64)
Execution time 236.48ms (± 0.15%) 236.51ms (± 0.17%) ~ 234.87ms 243.71ms p=0.586 n=600
tsserverlibrary-startup - node (v18.15.0, x64)
Execution time 232.29ms (± 0.16%) 232.22ms (± 0.16%) ~ 230.84ms 237.70ms p=0.058 n=600
typescript-startup - node (v18.15.0, x64)
Execution time 228.14ms (± 0.17%) 228.22ms (± 0.16%) +0.08ms (+ 0.03%) 226.88ms 230.59ms p=0.035 n=600
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • tsc-startup - node (v18.15.0, x64)
  • tsserver-startup - node (v18.15.0, x64)
  • tsserverlibrary-startup - node (v18.15.0, x64)
  • typescript-startup - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

// the root is `file://Users/`
assert.strictEqual(ts.getNormalizedAbsolutePath("file://Users/matb/projects/san/../../../../../../typings/@epic/Core.d.ts", ""), "file://Users/typings/@epic/Core.d.ts");
// this is real
assert.strictEqual(ts.getNormalizedAbsolutePath("file:///Users/matb/projects/san/../../../../../../typings/@epic/Core.d.ts", ""), "file:///typings/@epic/Core.d.ts");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk if we want to preserve specific examples in these, but that might be fine.

Maybe we should have tests on untitled:?

return path;
}
// Some paths only require cleanup of `/./` or leading `./`
const simplified = path.replace(/\/\.\//g, "/").replace(/^\.\//, "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're already here, I'd also recommend

Suggested change
const simplified = path.replace(/\/\.\//g, "/").replace(/^\.\//, "");
let simplified = path.replace(/\/\.\//g, "/");
if (simplified.startsWith("./") {
simplified = simplified.slice(2);
}

Copy link
Member Author

@andrewbranch andrewbranch Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed a small but measurable improvement. Nice!

src/compiler/path.ts Outdated Show resolved Hide resolved
normalized = path.substring(0, normalizedUpTo);
}
}
else if (segmentLength === 2 && path.charCodeAt(index) === CharacterCodes.dot && path.charCodeAt(index + 1) === CharacterCodes.dot) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: If the previous segmentLength was 1, but the segment was not ., this performs an unnecessary recheck of segmentLength === 2.

src/compiler/path.ts Outdated Show resolved Hide resolved
src/compiler/path.ts Outdated Show resolved Hide resolved
src/compiler/path.ts Outdated Show resolved Hide resolved
src/compiler/path.ts Show resolved Hide resolved
Comment on lines 661 to 662
const sepIndex = path.indexOf(directorySeparator, index + 1);
const altSepIndex = path.indexOf(altDirectorySeparator, index + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or use findIndex(path, isAnyDirectorySeparator, index + 1)

@andrewbranch
Copy link
Member Author

andrewbranch commented Dec 20, 2024

From instrumenting the compilation of VS Code, I learned two things:

  1. The number of normalizePath calls outweighs getNormalizedAbsolutePath by ~300x.
  2. 99% of all calls to either function end up being a no-op.

Optimizing getNormalizedAbsolutePath is unlikely to make a measurable difference.

I'm going to repeat the instrumentation for a TS Server program update and see if the ratios are similar.

@andrewbranch
Copy link
Member Author

During a TS Server update, literally every call is a no-op.

{
  initialize: {
    normalizePath: {
      total: 108354,
      noop: 108026,
      slashes: 0,
      fastReplace: 0,
      full: 328
    },
    getNormalizedAbsolutePath: {
      total: 1978,
      noop: 1958
    }
  },
  update: {
    normalizePath: {
      total: 7839,
      noop: 7839,
      slashes: 0,
      fastReplace: 0,
      full: 0
    },
    getNormalizedAbsolutePath: {
      total: 467,
      noop: 467
    }
  }
}

@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 8, 2025

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
pack this ✅ Started ❌ Results

@typescript-bot
Copy link
Collaborator

Hey @DanielRosenwasser, something went wrong when looking for the build artifact. (You can check the log here).

@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 8, 2025

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jan 8, 2025

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/164499/artifacts?artifactName=tgz&fileId=C363503DDC9CF8EDD088ADAB07110C96DF6B54D1E2E2CDD0508EAC13AAB8CE4D02&fileName=/typescript-5.8.0-insiders.20250108.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;

@andrewbranch
Copy link
Member Author

andrewbranch commented Jan 9, 2025

ts  - getNormalizedAbsolutePath - non-normalized inputs x 312,203 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.13us...3.35us)
new - getNormalizedAbsolutePath - non-normalized inputs x 470,033 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(2.12us...2.14us)
ts  - normalizePath             - non-normalized inputs x 279,383 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.51us...3.74us)
new - normalizePath             - non-normalized inputs x 317,772 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.13us...3.17us)

ts  - getNormalizedAbsolutePath - normalized inputs  x 1,351,618 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(727.40ns...753.29ns)
new - getNormalizedAbsolutePath - normalized inputs  x 9,384,673 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(105.79ns...106.60ns)
ts  - normalizePath             - normalized inputs x 11,299,524 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(87.34ns...89.66ns)
new - normalizePath             - normalized inputs x 11,162,477 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(88.69ns...90.97ns)

ts  - getNormalizedAbsolutePath - normalized inputs (long)   x 239,527 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(4.13us...4.22us)
new - getNormalizedAbsolutePath - normalized inputs (long) x 3,004,483 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(331.61ns...333.89ns)
ts  - normalizePath             - normalized inputs (long) x 3,221,628 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(307.32ns...315.50ns)
new - normalizePath             - normalized inputs (long) x 3,213,039 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(310.61ns...312.85ns)

ts  - tsc-vscode-macos.json   x 2.44 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(406.30ms...414.83ms)
new - tsc-vscode-macos.json   x 2.45 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(404.74ms...414.85ms)
ts  - tsc-vscode-windows.json x 2.63 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(373.04ms...389.78ms)
new - tsc-vscode-windows.json x 2.74 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(363.90ms...367.53ms)

ts  - tsserver-edit-vscode-macos.json   x 2,220 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(437.21us...457.24us)
new - tsserver-edit-vscode-macos.json   x 4,930 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(200.00us...203.69us)
ts  - tsserver-edit-vscode-windows.json x 2,521 ops/sec (12 runs sampled) v8-never-optimize=true min..max=(380.36us...405.09us)
new - tsserver-edit-vscode-windows.json x 5,392 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(182.71us...187.61us)

ts  - tsserver-startup-vscode-macos.json   x 219 ops/sec (9 runs sampled) v8-never-optimize=true min..max=(4.44ms...4.57ms)
new - tsserver-startup-vscode-macos.json   x 256 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.85ms...4.00ms)
ts  - tsserver-startup-vscode-windows.json x 256 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(3.88ms...3.93ms)
new - tsserver-startup-vscode-windows.json x 294 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.36ms...3.47ms)

@andrewbranch
Copy link
Member Author

After latest commit:

ts  - getNormalizedAbsolutePath - non-normalized inputs x 302,861 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(3.21us...3.45us)
new - getNormalizedAbsolutePath - non-normalized inputs x 536,370 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(1.79us...1.91us)
ts  - normalizePath             - non-normalized inputs x 237,263 ops/sec (9 runs sampled) v8-never-optimize=true min..max=(3.59us...3.80us)
new - normalizePath             - non-normalized inputs x 383,873 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(2.54us...2.68us)

ts  - getNormalizedAbsolutePath - normalized inputs  x 1,303,039 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(749.03ns...839.55ns)
new - getNormalizedAbsolutePath - normalized inputs  x 8,795,269 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(111.05ns...114.70ns)
ts  - normalizePath             - normalized inputs x 10,916,299 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(89.41ns...95.17ns)
new - normalizePath             - normalized inputs x 10,677,227 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(90.96ns...98.74ns)

ts  - getNormalizedAbsolutePath - normalized inputs (long) x 231,771 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(4.17us...4.59us)
new - getNormalizedAbsolutePath - normalized inputs (long) x 2,899,659 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(337.72ns...360.04ns)
ts  - normalizePath - normalized inputs (long) x 2,996,074 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(310.80ns...332.25ns)
new - normalizePath - normalized inputs (long) x 3,096,857 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(312.29ns...328.02ns)

ts  - tsc-vscode-macos.json   x 2.39 ops/sec (9 runs sampled) v8-never-optimize=true min..max=(406.07ms...418.08ms)
new - tsc-vscode-macos.json   x 2.45 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(401.52ms...422.69ms)
ts  - tsc-vscode-windows.json x 2.62 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(379.20ms...386.33ms)
new - tsc-vscode-windows.json x 2.77 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(358.76ms...361.70ms)

ts  - tsserver-edit-vscode-macos.json   x 2,232 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(444.66us...453.18us)
new - tsserver-edit-vscode-macos.json   x 4,895 ops/sec (12 runs sampled) v8-never-optimize=true min..max=(202.00us...208.18us)
ts  - tsserver-edit-vscode-windows.json x 2,536 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(390.12us...400.87us)
new - tsserver-edit-vscode-windows.json x 5,320 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(186.94us...189.56us)

ts  - tsserver-startup-vscode-macos.json   x 216 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(4.54ms...4.71ms)
new - tsserver-startup-vscode-macos.json   x 247 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(4.02ms...4.11ms)
ts  - tsserver-startup-vscode-windows.json x 247 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.95ms...4.17ms)
new - tsserver-startup-vscode-windows.json x 291 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(3.36ms...3.54ms)

and just comparing the last commit to the one before it:

old - getNormalizedAbsolutePath - non-normalized inputs x 449,445 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(2.20us...2.27us)
new - getNormalizedAbsolutePath - non-normalized inputs x 564,347 ops/sec (12 runs sampled) v8-never-optimize=true min..max=(1.74us...1.79us)
old - normalizePath             - non-normalized inputs x 307,495 ops/sec (10 runs sampled) v8-never-optimize=true min..max=(3.22us...3.27us)
new - normalizePath             - non-normalized inputs x 396,067 ops/sec (11 runs sampled) v8-never-optimize=true min..max=(2.49us...2.55us)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
Status: Waiting on author
Development

Successfully merging this pull request may close these issues.

4 participants