Rejit - prototype of a non-backtracking, just-in-time, SIMD-able regexp compiler
coreperf.com
coreperf.com
Called the project 'jitre'.
Damn it!
P.S. I suggest to add libpcre with and without JIT to the set of benchmarks. RE2 is not exactly the speediest library.
SSE4.2 is not mandatory. Rejit works without it as well (SSE support detected dynamically), it just gives excellent performance with a relatively simple implementation. Support for earlier versions of SSE can easily be added.
I'll try to add libpcre to the benchmarks when I get some time.
For general-purpose applications (e.g. use in programming languages) people usually want a regex flavor with support for at least backreferences and typically also (recursive) subpattern references. Note: Adding support for backreferences makes matching regexes an NP-complete problem (as opposed to a simple linear-time algorithm without them).
(But of course, having fast NFA implementations for really-regular regexes is still useful. After all a large part of the regexes you typically write will not use backreference etc)
This is only partially true: while most people use implementations which support back references, it's likely that a significant percentage of regular expressions actually executed do not use that complexity. Given the widespread use of regular expressions for input validation, log-file analysis, URL dispatching in web frameworks, etc. there's a fair chance that a majority of the regular expressions executed would benefit from this approach, particularly since it would be trivial for an engine to transparently fall down to the current implementation when it encounters a complex construct.
These are also cases where it's likely okay to omit back-references and the more complex options which give rise to exponential time.
Edit: So we can keep the best of both worlds !
http://ridiculousfish.com/blog/posts/old-age-and-treachery.h...
$ time grep -R "yoyo\|regexp" linux-3.10.6 > /dev/null real 0m2.138s user 0m1.875s sys 0m0.252s
$ time jrep -R "yoyo|regexp" linux-3.10.6 > /dev/null real 0m0.411s user 0m0.135s sys 0m0.270s
> we shall make a one gigabyte file with one thousand x's per line, and time grep searching for "yy" (a two character best case) and "yx" (a two character worst case).
In this case SSE based code will be a) several times faster because SSE loads will be used, b) time difference between "yy" and "xx" cases will be minimal (several ticks to accumulate result from second PMOVMSKB+PCMPEQB combo and c) time of search will be background-independent.
Paraphasing Linux CodingStyle text, first off, I'd suggest printing out a copy of the "why GNU grep is fast", and NOT read it. Burn them, it's a great symbolic gesture.
The trivial exercise is to disassemble x86-64 version of glibc memchr(3) and try to outperform it with byte-at-a-time based code.
Hint: you won't be able to do it.
You might find DynASM[1] useful, as long as you're not doing dynamic register allocation. Here's[2] a good tutorial.
[1]: http://luajit.org/dynasm.html
[2]: http://blog.reverberate.org/2012/12/hello-jit-world-joy-of-simple-jits.htmlPossibly measurement error, though, considering JS time in milliseconds and the different test methodology for v8 under a certain number of trials, as compared with other engines?