Created
July 15, 2011 14:42
-
-
Save jfahrenkrug/1084817 to your computer and use it in GitHub Desktop.
Test showcasing how slow the new Ragel-based Radius parser is
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%{ | |
machine parser; | |
action _prefix { mark_pfx = p } | |
action prefix { | |
if data[mark_pfx..p-1] != @prefix | |
closing = data[mark_pfx-1,1] == '/' | |
@nodes.last << data[mark_pfx-(closing ? 2 : 1)..p] | |
fbreak; | |
end | |
} | |
action _starttag { mark_stg = p } | |
action starttag { @starttag = data[mark_stg..p-1] } | |
action _attr { mark_attr = p } | |
action attr { | |
@attrs[@nat] = @vat | |
} | |
action prematch { | |
@prematch_end = p | |
@prematch = data[0..p] if p > 0 | |
} | |
action _nameattr { mark_nat = p } | |
action nameattr { @nat = data[mark_nat..p-1] } | |
action _valattr { mark_vat = p } | |
action valattr { @vat = data[mark_vat..p-1] } | |
action opentag { @flavor = :open } | |
action selftag { @flavor = :self } | |
action closetag { @flavor = :close } | |
action stopparse { | |
@cursor = p; | |
fbreak; | |
} | |
Closeout := empty; | |
# words | |
PrefixChar = [\-A-Za-z0-9._?] ; | |
NameChar = [\-A-Za-z0-9._:?] ; | |
TagName = NameChar+ >_starttag %starttag; | |
Prefix = PrefixChar+ >_prefix %prefix; | |
Name = Prefix ":" TagName; | |
NameAttr = NameChar+ >_nameattr %nameattr; | |
Q1Char = ( "\\\'" | [^'] ) ; | |
Q1Attr = Q1Char* >_valattr %valattr; | |
Q2Char = ( "\\\"" | [^"] ) ; | |
Q2Attr = Q2Char* >_valattr %valattr; | |
Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr; | |
Attrs = (space+ Attr* | empty); | |
CloseTrailer = "/>" %selftag; | |
OpenTrailer = ">" %opentag; | |
Trailer = (OpenTrailer | CloseTrailer); | |
OpenOrSelfTag = Name Attrs? Trailer; | |
CloseTag = "/" Name space* ">" %closetag; | |
SomeTag = '<' (OpenOrSelfTag | CloseTag); | |
main := |* | |
SomeTag => { | |
tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs} | |
@prefix = nil | |
@name = nil | |
@flavor = :tasteless | |
@attrs = {} | |
@nodes << tag << '' | |
fbreak; | |
}; | |
any => { | |
@nodes.last << data[p] | |
@tagstart = p | |
}; | |
*|; | |
}%% | |
module Radius | |
class Scanner | |
def operate(prefix, data) | |
# data = data.unpack('c*') | |
buf = "" | |
csel = "" | |
@prematch = '' | |
@starttag = nil | |
@attrs = {} | |
@flavor = :tasteless | |
@cursor = 0 | |
@tagstart = 0 | |
@nodes = [''] | |
remainder = data.dup | |
until remainder.length == 0 | |
p = perform_parse(prefix, remainder) | |
remainder = remainder[p..-1] | |
end | |
return @nodes | |
end | |
private | |
def perform_parse(prefix, data) | |
stack = [] | |
p = 0 | |
ts = 0 | |
te = 0 | |
act = 0 | |
eof = data.length | |
@prefix = prefix | |
%% write data; | |
%% write init; | |
%% write exec; | |
return p | |
end | |
end | |
end | |
string = 'a' * 460000 | |
puts "Starting at #{t = Time.now}" | |
Radius::Scanner.new.operate('r', string) | |
puts "Done at #{t2 = Time.now}. Took #{t2 - t} seconds." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment