Live data from Hacker News

Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

branchfree.org

31–37 of 37 posts

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#31

I'm drawn to hairy parsers for implementing DSL-rich syntactically-extensible programming languages. Hairy, as in, extensible and scoped; full-ish Perl-compatible RE, including parse-influencing code execution; n-ary multifix operator precedence; backtrack/operator-precedence/regex sandwiches. Subengines can be used to variously strength reduce parts of the grammar, and to dynamically prune search. It's been some yea…

I like the UVa guys, but MNCaRT isn't very mature and was mostly there to support the Automata Processor. Since Micron kicked that product out the door (into a startup that might be charitably described as 'moribund', Natural Intelligence Semiconductor) there's not much point in starting with that codebase.

Some customers used Hyperscan as a primary matching engine with a secondary state machine / parser behind, but I'm not at liberty to discuss specifics. In any case these guys were interested in network threat detection, not generalized parsing.

I wouldn't use RE2::Set for language parsing, as it can only tell you that certain patterns occurred, but won't give you offsets, just a single bit.

The problem with the charmingly described 'hairy parser' is that it will just be 'one damn thing after another' - a lot of code, a lot of weird semantic corners, etc. Why not just use a parser that's intended for generality - something like ANTLR? What will taping all that stuff together accomplish?

We didn't set out to create a huge codebase with weird corners with Hyperscan either, and we still got one. If you go out with the intent of building something hairy from the start.... :-/

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#32
post #11

This appears to be the same algorithm used by ripgrep ( https://github.com/BurntSushi/ripgrep ) for searching when SIMD/AVX is enabled. Specifically, it uses the algorithm Teddy from the library that’s derived from this paper.

Yes, ripgrep (or specifically, the Rust regex crate) takes inspiration from Hyperscan for its SIMD matching. https://github.com/rust-lang/regex/commit/203c509df9e1dcba61... Both libraries also rely on a number of techniques from existing published research. Hyperscan is ruthlessly optimized for x86 platforms, but has dropped support for non-x86 platforms. Rust's regex crate is designed more as a general purpose, port…

I like 'ruthlessly'. It sounds very butch, especially applying to an activity largely carried out by seated, balding men hunched over terminals in an office.

Rust regex is suited to wide scale use. By comparison to Hyperscan, it is not suited to the kind of large scale cases that Hyperscan handles, but it's well done.

Many of Hyperscan techniques are sui generis, not published. Hopefully some of that will be rectified over time.

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#33

I'm drawn to hairy parsers for implementing DSL-rich syntactically-extensible programming languages. Hairy, as in, extensible and scoped; full-ish Perl-compatible RE, including parse-influencing code execution; n-ary multifix operator precedence; backtrack/operator-precedence/regex sandwiches. Subengines can be used to variously strength reduce parts of the grammar, and to dynamically prune search. It's been some yea…

I like the UVa guys, but MNCaRT isn't very mature and was mostly there to support the Automata Processor. Since Micron kicked that product out the door (into a startup that might be charitably described as 'moribund', Natural Intelligence Semiconductor) there's not much point in starting with that codebase. Some customers used Hyperscan as a primary matching engine with a secondary state machine / parser behind, but…

Ah, ok, thanks.

Let's see... I'm coming at this with objectives around programming experience, rather than around parser implementation. I want to be able to do grammar design that is tightly tied to problem domain expression, rather than to parser tech. The usual dance, of adapting a pretty problem-domain grammar to available parsers, by grammar uglification, transformation, and kludgery... I'd like that to be optional - a thing of optimization, not of minimum viable effort. I'd ideally like parser design choices to escape the parser only as performance variance.

So yes, I'd love a general parser generator, that accepts any grammar, and ideally does some reasonable best-effort transformation and compilation to subengines given the mess you've handed it. I've not seen that. But since I'd not seen RE2::Set, it's perhaps been a decade since I seriously looked around, so maybe there's new niftyness?

I've tried ANTLR a couple of times over the years, at least for toys, maybe a no-templates C++ parser. (It was weird - I never figured it out, and it's not a happened with anything else, but I just viscerally disliked working with it.) Others... None were without sacrifices that required them being wrapped in hair.

So I dreamed of someone creating a parser generator toolkit, a library of engines, reusable rather than inextricably tangled in yet another parser silo. I saw Hyperscan and thought, hmm... might a toolkit come with a regexp api? :)

A rich parser doesn't have to be complex, if you sacrifice speed. A Perl 5 compatible (some old version) regexp engine can be done in a page or two of prolog. So I used to focus on expressivity, and then scramble to get back to minimally tolerable performance.

Minimum-viable compiler performance is arguably dropping dramatically now. With cloud-parallel deterministic compilation, and community-scale caching. So maybe something simple could now have viable pragmatics.

I saw Hyperscan, and was hit by old dreams of speed. Multiple wizzy subengines woven together. I'd woven in GLRs before, but multiple patterns... oooh, what leverage might might be found there?! :)

> What will taping all that stuff together accomplish?

Extensible and scoped parsing... the immensely expensive Python 2 to 3 transition was in part a design choice to avoid scoped method dispatch and file-scoped parsing of both languages. I suggest it was the wrong call.

PCRE with parse-affecting code... say rather, each time you lose a feature, some set of problems gets harder. I'd prefer that to be the harder-slower of falling back to a less-specialized engine (which sometimes isn't a problem), to the harder-go-back-and-rewrite of nonimplementation (which always is). Grammar restriction as premature optimization.

N-ary multifix operators... lets you easily parse expressions of rich operators, from Smalltalk to math. Modern IDEs seem sufficient to address puzzlement over "how and why did this (not)parse".

A "sandwich" of regexp for tokens, operator precedence parser for extensible expressions, and something backtracking for an extensible list of statements, is one way to get a somewhat traditional language parser that's more nicely extensible and expressive.

> a lot of weird semantic corners

Yes, but... I'd like the choice to avoid semantic weirdness, or not, to happen at the application level, not at the parser api level. Because it's a tradeoff. I accept the PEG argument that often simplicity and composability is the right design choice, is worth the expressive cost. But not the argument that anything PEGs can't handle is a "legacy language" which people shouldn't be using anyway (fun conversation with a PEG person).

So yes, I'd like to see programming language parsing become far richer than currently, and thus somewhat hairier. Because avoiding that is, I suggest, inflicting far greater costs elsewhere.

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#35
post #34

I’m curious how Hyperscan compares to the venerable re2c, which is used for compiling SpamAssassin’s rules.

glangdale can probably say more, but I think the high level answer is pretty easy: re2c is intensely focused on building state machines, in their entirety, ahead of time. There's also some cool stuff that lets you integrate the state machine with the rest of your code. AFAIK, re2c sticks fairly strictly to state machines and doesn't do sophisticated optimizations like Hyperscan, particularly with respect to literals. To me, they are fundamentally solving different problems. re2c is only viable if you can actually deal with the full size of the DFAs you build.

re2c is also notable for, AIUI, having a very principled solution to the problem of submatch extraction using tagged DFAs. They wrote a paper about it: http://re2c.org/2017_trofimovich_tagged_deterministic_finite...

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#36
post #34

I’m curious how Hyperscan compares to the venerable re2c, which is used for compiling SpamAssassin’s rules.

glangdale can probably say more, but I think the high level answer is pretty easy: re2c is intensely focused on building state machines, in their entirety, ahead of time. There's also some cool stuff that lets you integrate the state machine with the rest of your code. AFAIK, re2c sticks fairly strictly to state machines and doesn't do sophisticated optimizations like Hyperscan, particularly with respect to literals.…

For what it's worth at this late stage:

Yes, this is an accurate summary. re2c works when it works, and there's clearly a good niche for "pattern matching stuff that determinizes cleanly". However, in the general case, DFAs catch fire (combinatorial explosion in # of states), especially when handling multiple regular expressions.

IIRC SpamAssassin has lots of quite hard patterns and re2c can only handle a subset. I forget what the fallback position is (libpcre?).

Re: Hyperscan: A Fast Multi-Pattern Regex Matcher for Modern CPUs

#37
post #17

Author here, in case anyone wants to question, abuse, argue, etc.

I ported Hyperscan to ARM several months ago with help from the following project: https://github.com/nemequ/simde Would you be interested in working together to get an ARM port that's a bit cleaner and author-approved?

Does the ARM version hyperscan work well? Can you describe the detailed steps? Thanks
Post reply on HN