Skip to content

Conversation

@blakeembrey
Copy link
Member

@blakeembrey blakeembrey commented Jan 22, 2026

Almost a 100% performance improvement with these parsing changes, notably removing .split() and removing .trim(), and using a loop instead of a regex to validate numbers. This is the rough order of optimization and improvement:

Before:

 ✓ src/index.bench.ts > parseRange 2205ms
     name                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · 1000 byte range       4,993,061.92  0.0001  1.9072  0.0002  0.0002  0.0003  0.0003  0.0010  ±0.87%  2496531
   · multiple byte ranges  1,361,804.35  0.0006  0.2075  0.0007  0.0007  0.0009  0.0010  0.0037  ±0.43%   680903

Removing array assignment (use object return):

 ✓ src/index.bench.ts > parseRange 2240ms
     name                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · 1000 byte range       5,323,845.39  0.0001  1.6439  0.0002  0.0002  0.0002  0.0003  0.0009  ±0.93%  2661923
   · multiple byte ranges  1,394,318.85  0.0006  0.2097  0.0007  0.0007  0.0009  0.0010  0.0037  ±0.49%   697160

Validate number in loop and remove .trim():

 ✓ src/index.bench.ts > parseRange 2448ms
     name                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · 1000 byte range       6,607,117.15  0.0000  1.8297  0.0002  0.0002  0.0002  0.0002  0.0003  ±1.00%  3303559
   · multiple byte ranges  1,731,118.69  0.0005  0.2345  0.0006  0.0006  0.0007  0.0007  0.0031  ±0.47%   865560

Remove .split() and use string slicing:

 ✓ src/index.bench.ts > parseRange 3023ms
     name                            hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · 1000 byte range       9,609,063.96  0.0000  1.9986  0.0001  0.0001  0.0001  0.0002  0.0004  ±1.17%  4804533
   · multiple byte ranges  2,480,507.17  0.0003  0.2010  0.0004  0.0004  0.0005  0.0005  0.0010  ±0.32%  1240254

The parser is fairly similar to cookie now, so I knew the optimizations to make already. I think there's still something in the handling of missing values but it seems negligible for the effort.

/argument str must be a string/,
);
});
import { parse, combineRanges } from "./index";
Copy link
Member Author

Choose a reason for hiding this comment

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

Part of the change is removing options.combineRanges in favor of a separate utility. The change is negligible for performance so it could remain an option 🤷

It is a code path that never needs checking if it's included in downstream users code though, and it makes it easier to perf test, which is why I split it apart.

@bjohansebas bjohansebas self-requested a review January 22, 2026 21:07
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

Successfully merging this pull request may close these issues.

1 participant