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
加载中
想要评论请 注册 或 登录