Skip to content

Instantly share code, notes, and snippets.

@jfahrenkrug
Created July 15, 2011 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfahrenkrug/1084817 to your computer and use it in GitHub Desktop.
Save jfahrenkrug/1084817 to your computer and use it in GitHub Desktop.
Test showcasing how slow the new Ragel-based Radius parser is
%%{
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