Skip to content
代码片段 群组 项目
未验证 提交 aeafec33 编辑于 作者: Stan Hu's avatar Stan Hu
浏览文件

Reduce memory allocations when iterating over an Enumerator

https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88882 introduced
a monkey patch for `Enumeration#next` to improve stack traces for
Gitaly calls due to https://bugs.ruby-lang.org/issues/16829.

This patch relies on checking that `gitlab_patch_backtrace_marker` is
present in the stack trace. However, for a Rust extension like
`prometheus-client-mmap`, the Ruby interpreter omits the details of
the calls made inside the extension. For example, in
https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/8373#note_1748497473,
we see `StopIteration` is raised when the extension iterates through
all strings in its `WeakMap`, but the backtrace does not contain the
expected signature since `Enumerator#next` is called from the Rust
code. As a result, the backtrace would always be unnecessarily
appended to the `StopIteration` exception, resulting in millions of
wasted memory allocations.

This commit reduces memory allocations in two ways:

1. Use a constant for the regular expression. This eliminates the need
to call `parse_regexp` in the Ruby interpreter repeatedly each time
`Enumerator#next` is called.

2. Don't append stack traces for `StopIteration`. A Enumerator raises
`StopIteration` when the end is reached, and `Kernel#loop` rescues this
exception. Previously a lot of care went into ensuring that nested
enums preserved the full backtrace when `StopIteration` occurred, but
this generally isn't needed for debugging. If a C or Rust extension
iterates through an array repeatedly, we saw millions of temporary
objects being created to build the complete stack trace for no real
use.

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/439920

Changelog: performance
上级 0f1134c6
No related branches found
No related tags found
加载中
加载中
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册