So months later I finally got time to do a comparison with fprof. I am on Max OS X, Erlang 18.1 and Elixir 1.1.1. I ran with MIX_ENV=prod, `iex -S mix compile`. the output said my protocols were consolidated.
I tried using fprof, and couldn't glean much, except some data that the Pratt Parser lexer was noticeably slower. the difference there is that my recursive descent library uses a "hard-coded" cond to match the available tokens, and then create them. For my Pratt parser, I use protocol dispatch to create the token. (I did this to make my code organization easier, as my token structs implement their create and the Pratt parser functions all in one token file, which means fewer places to change when modifying items, shorter files, and easier addition of new tokens.
Switching to use a cond in the lexer and not using protocol dispatch dropped my :
timer.tc timings of 100 evaluations of a test input from 230000 to 150000 with just that change. It was still overall slower than the RD library, but I'm guessign that also has to do with the protocol dispatching I do on the evaluation side.
Is this just the way things are, or am I missing an optimization that allows me to keep using protocols (which I find more elegant)?