-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Right size regular expression compile buffers #2696
Conversation
No strong opinion (== very well written). |
Nice writeup, a few semi-educated reactions:
|
ACK, I'll look into |
@byroot pushed 3cb5bf0 as per your guidance on regular expressions being immutable anyways. And ousted Booting redmine:
50% improvement on previous numbers - about 469kb of excess compile buffer trimmed. |
nice ! |
re.c
Outdated
@@ -2954,7 +2954,7 @@ static void | |||
reg_resize(regex_t *reg) | |||
{ | |||
if (reg->alloc > reg->used) { | |||
unsigned char *new_ptr = xrealloc(reg->p, reg->used); | |||
unsigned char *new_ptr = ruby_sized_xrealloc(reg->p, reg->used, reg->capa); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use ruby_sized_xrealloc
in this file.
reg->p
is allocated in onig_bbuf_init
where xmalloc
is not ruby_xmalloc
.
|
b7b0e70
to
2664e66
Compare
In e07d9b6 migrated the resize function as Debug counters on a recent Redmine install:
Thank you for the always constructive feedback. Is there any value in an upstream oniguruma patch as it currently isn't just Ruby specific? I don't know how the workflow works, but can investigate if there's value beyond this patch. |
2664e66
to
e07d9b6
Compare
It feels too invasive to access Ruby's debug counters inside onigmo, for me. |
Totally makes sense - felt like jumping through too many hoops to get in there as well - decoupled and removed in 03f35de |
regcomp.c
Outdated
reg->p = new_ptr; | ||
} | ||
} | ||
if (reg->chain) onig_reg_resize(reg->chain); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you expect all compilers to optimize tail-calls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'd expect gcc and clang to with opt level 3, but we cannot rely on that. Or the behavior of other compilers. I replaced the recursive call with a goto instead in 1ff3033
cacbab2
to
dec359f
Compare
dec359f
to
60ce291
Compare
@nobu anything else left to do here? I squashed to 1 commit and addressed the suggestion about not assuming tail call optimization. |
As a continuation of type specific resize on freeze implementations of String and Array and looking into the
Regexp
type I found these memory access patterns for regular expression literals:Digging a little further and remembering some context of previous oniguruma memory investigation I remembered the pattern buffer struct has a compile buffer with a simple watermark for tracking used space. This changeset implements
reg_resize
(static asary_resize
) which attempts to right size the compile buffer if over allocated at the following sites:rb_reg_freeze
and pointRegexp#compile
to itchain
member which points to anotherregex_t
on the struct if present, but have not been able to find references to it in the source tree other than for freeing a regex or inspecting it's memory footprint.I introduced 2 new debug counters, which yields the following results on booting Redmine on Rails 5:
About 300kb reallocated across 6319 oversized instances.
An example of
Regexp#freeze
There is likely more layers that can be peeled back here, but keeping it simple and concise for review.
@shyouhei @byroot thoughts?