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.

GemTime per requestObjects per request
browser 6.2.0110 µs245
BrowserX 1.0.061 µs129

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