Benchmarks
One benchmark, the shape of a web request, run against browser 6.2.0 and BrowserX 1.0.0.
Per request
Ruby 4.0.9 with YJIT, median of 7 runs.
| Gem | Time per request | Objects per request |
|---|---|---|
| browser 6.2.0 | 110 µs | 245 |
| BrowserX 1.0.0 | 61 µs | 129 |
bench/request.rb asks each user agent what a web request asks: the browser’s name and full version, bot? and the bot’s name, the platform’s name and version, device.mobile?, device.tablet? and the first accepted language. It runs over 2,000 distinct user agents sampled from the corpus, then over 20 of them repeated.
Why it is faster
Bots. browser matches the user agent against the bot list one entry at a time. BrowserX nests the list by common prefix into one regexp, which follows a single branch per character, and rebuilds it only when the list grows or is replaced.
No second detection. The built-in bot matchers ignore the browser, so bot? no longer builds a second Browser for the same user agent. Custom matchers still receive one.
Lazy matchers. Platform and device matchers are built only when a request asks for the platform or the device.
Reproduce
Run it without JIT and with --yjit, for upstream and for BrowserX, one at a time on an otherwise idle machine. path/to/upstream is a plain clone of fnando/browser at dd88933.
ruby --yjit -I path/to/upstream/lib bench/request.rb
ruby --yjit -I lib bench/request.rb