06af9a1e38
After the move to PCRE2, optimizing patterns has been a thorn in the side due to the fact that PCRE2's JIT compiler modifies the pattern object itself (instead of returning a new set of data, like PCRE1 did). To make this fit with the existing behavior, a read/write lock was introduced, with the read part locking when matching and the write when compiling (or JIT-compiling) the pattern. This locking strategy however introduced a performance issue, as we needed: * to acquire a write lock to compile/optimize the pattern (incl. the common case where the pattern was already compiled, so bailing out immediately); * to acquire a read lock during the actual match, to prevent some other thread from optimizing the pattern under our nose. This was due to the "lazy" optimization policy of QRegularExpression -- optimize a pattern after a certain number of usages. The excessive amount of locking effectively limited scalability. Simplify the code, and drop that policy altogether: since JIT compiling in PCRE2 is faster and pretty much "always recommended", just always do it for any pattern (unless it gets disabled via env variables) when compiling it. This allows to go back to a plain QMutex, and now the actual matching doesn't require acquiring any locks any longer. Of course, there is still a mutex acquired just before matching for checking whether the pattern needs recompiling in the first place; this can probably be further optimized via double-checked locking (using atomics), but not doing it right now. This shift makes a couple of pattern options controlling optimization useless, and allows to centralize the 3 QRegularExpression tests (which were actually the very same test, just setting slightly different optimizations strategies). While at it, install a stress-test for threading, with the idea of running it under TSAN or helgrind to catch bugs in QRegularExpression's locking. [ChangeLog][Important Behavior Changes][QRegularExpression] Regular expressions are now automatically optimized (including JIT compiling) on their first usage. The pattern options OptimizeOnFirstUsageOption and DontAutomaticallyOptimizeOption no longer have any effect, and will get removed in a future version of Qt. QRegularExpression::optimize() can be still used to compile and optimize the regular expression in advance (before any match), if needed. Task-number: QTBUG-66781 Change-Id: Ia0e97208ae78255fe811b78029ed01c204e47bd2 Reviewed-by: David Faure <david.faure@kdab.com> |
||
---|---|---|
.. | ||
collections | ||
containerapisymmetry | ||
qalgorithms | ||
qarraydata | ||
qarraydata_strictiterators | ||
qbitarray | ||
qbytearray | ||
qbytearraylist | ||
qbytearraymatcher | ||
qbytedatabuffer | ||
qcache | ||
qchar | ||
qcollator | ||
qcommandlineparser | ||
qcontiguouscache | ||
qcryptographichash | ||
qdate | ||
qdatetime | ||
qeasingcurve | ||
qexplicitlyshareddatapointer | ||
qfreelist | ||
qhash | ||
qhash_strictiterators | ||
qhashfunctions | ||
qlatin1string | ||
qline | ||
qlinkedlist | ||
qlist | ||
qlist_strictiterators | ||
qlocale | ||
qmacautoreleasepool | ||
qmap | ||
qmap_strictiterators | ||
qmargins | ||
qmessageauthenticationcode | ||
qpair | ||
qpoint | ||
qpointf | ||
qqueue | ||
qrect | ||
qregexp | ||
qregularexpression | ||
qringbuffer | ||
qscopedpointer | ||
qscopedvaluerollback | ||
qset | ||
qsharedpointer | ||
qsize | ||
qsizef | ||
qstl | ||
qstring | ||
qstring_no_cast_from_bytearray | ||
qstringapisymmetry | ||
qstringbuilder | ||
qstringiterator | ||
qstringlist | ||
qstringmatcher | ||
qstringref | ||
qstringview | ||
qtextboundaryfinder | ||
qtime | ||
qtimeline | ||
qtimezone | ||
qvarlengtharray | ||
qvector | ||
qvector_strictiterators | ||
qversionnumber | ||
tools.pro |