On Tue, Sep 18, 2007 at 01:17:41PM +0100, Brian Candler wrote:
> Here's an outline of how I think it could be done.
Incidentally, there's some scope for further optimisation here. Given that
the applications with large numbers of routes are likely to be
resource-based, e.g.
/foos
/foos/:id
/foos/new
/foos/:id/edit
/foos/:id/:action
then it may be worth reflecting this in the structure of the composed regexp
by matching the shared prefix only once. Trying to combine adjacent regexps
automatically may be hard, but resource routing could explicitly build
regexps this way.
The speed gains may not be significant in the bigger picture:
$ cat speed.rb
require 'benchmark'
include Benchmark
re1 = "(?: () /)\n"
re2 = "(?: () /)\n"
["things","bars","bazs","xyzs","abcs","foos","persons","admins"].each do |r|
re1 << <<EOS
| (?: () /#{r})
| (?: () /#{r}/(\\d+))
| (?: () /#{r}/new)
| (?: () /#{r}/(\\d+)/edit)
| (?: () /#{r}/(\\d+)/(\\w+))
EOS
re2 << <<EOS
| (/#{r} (
(?: () ) |
(?: () /new) |
(?: () (/\\d+) (
(?: () ) |
(?: () /edit) |
(?: () /(\\w+))
))
))
EOS
end
# Naive regexp
RE1 = %r{^(?:#{re1})$}x
# Prefix-optimised regexp
RE2 = %r{^(?:#{re2})$}x
N = 10_000
bm(6) do |test|
test.report("Match 1:") { N.times { raise unless RE1 =~ "/foos/123/edit" } }
test.report("Match 2:") { N.times { raise unless RE2 =~ "/foos/123/edit" } }
test.report("Mismatch 1:") { N.times { raise if RE1 =~ "/flurble/baz" } }
test.report("Mismatch 2:") { N.times { raise if RE2 =~ "/flurble/baz" } }
end
$ ruby speed.rb
user system total real
Match 1: 1.060000 0.000000 1.060000 ( 1.069919)
Match 2: 0.620000 0.000000 0.620000 ( 0.620281)
Mismatch 1: 0.640000 0.010000 0.650000 ( 0.636095)
Mismatch 2: 0.150000 0.000000 0.150000 ( 0.156758)
This is on a small laptop (Pentium M 1.1GHz), and shows an improvement of
about 44 microseconds per match when matching the sixth out of eight
resources.
It would be interesting to see how this compares with current routing
strategy though.
Regards,
Brian.
_______________________________________________
Merb-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/merb-devel