Inlining some rules into their parents and tossing in a (probably unnecessary) <commit> yields something about 1/3 faster:
$parser2 = new Parse::RecDescent(<<'EOS'); dictionary : '{' key_value(s /\|/) '}' { $return = { map { $_->[0] => $_->[1] } @{$item[2]} } } dictionary2 : key_value(s /\|/) '}' { $return = { map { $_->[0] => $_->[1] } @{$item[1]} } } key_value : /[A-Za-z0-9_ ]+/ '=' value { $return = [ @item[1,3] ] } value : '{' <commit> dictionary2 { $return = $item[3] } | /[^|\}]*/ EOS Calling new rules is slow, as is backtracking, but P::RD can't be speedy. You might try Perl6::Rules, which compiles to a regex. If you're lucky, it won't tickle any of the bugs in /(??{ ... })/ for your particular grammar, and should be faster. /s