sre_compile does bit test (e.g. `flags & SRE_FLAG_IGNORECASE`) in loop. `IntFlag.__and__` and `IntFlag.__new__` made it slower. So convert it to normal int before passing flags to `sre_compile()`.
| _MAXCACHE = 512 | ||
| def _compile(pattern, flags): | ||
| # internal: compile pattern | ||
| flags = int(flags) |
There was a problem hiding this comment.
The drawback of this change is that flags=1.0 and flags="0x1f" are accepted now.
There was a problem hiding this comment.
Maybe use the .value attribute?
# convert RegexFlag enum to integer for performance
try: flags = flags.value
except AttributeError: pass
Would it be expensive to add a "isinstance(flags, RegexFlags)"?
if isinstance(flags, RegexFlags): flags = flags.value
There was a problem hiding this comment.
Check what is the fastest method.
There was a problem hiding this comment.
LGTM.
I confirm that it's a real optimization: https://bugs.python.org/issue31671#msg303679
You might want to document it as an optimization in What's New in Python 3.7.
|
Will the contents of the cache leak back out to the user? It will be frustrating to use |
Last stage of |
sre_compile does bit test (e.g. flags & SRE_FLAG_IGNORECASE) in loop.
IntFlag.__and__andIntFlag.__new__made it slower.So convert it to normal int before passing flags to sre_compile.
https://bugs.python.org/issue31671