On 07/29/2012 11:43 AM, Erick Tryzelaar wrote:
Morning all,
I just finished my initial support for a Rust backend for Ragel, which
I describe on my blog:
Awesome!
Unfortunately there are some pretty severe performance issues at the moment.
Ragel supports two state machine styles, table-driven and goto-driven. My
backend uses tables, but since Rust doesn't yet support global constant
vectors, I need to malloc the state machine table on every function call. This
results in the [ragel-based url
parser](https://github.com/erickt/ragel/blob/rust/examples/rust/url.rl)
being about
10 times slower than the equivalent table-based parser in OCaml. You can see
the generated code [here](https://gist.github.com/3200980).
Yeah, we definitely need global constant vectors. You can work around it
to some degree by preallocating the constant vector and threading it around.
The `goto` route could be promising to explore. We could simulate it using
mutually recursive function calls. OCaml does this. But again, since Rust
doesn't support tailcalls (and may
[ever](https://github.com/mozilla/rust/issues/217)), we could run into a stack
explosion. It may work well for small grammars though, and maybe LLVM could
optimize calls into tailcalls.
There's a bug open on labeled break and continue -- this is needed for
the HTML5 parser too.
LLVM should do sibling call optimization. This means that, as long as
the function you're tail calling has the same number of arguments, it
should become a tail call. This may work for your use case.
I personally think we should try guaranteed tail call optimization at
some point and see whether it hurts performance. Note that this involves
switching to Pascal-style calling conventions, which means that the
runtime will need to change a bit.
Patrick
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev