Skip to content
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

Avoid using caller unless it will be used #62

Merged

Conversation

technicalpickles
Copy link
Contributor

@technicalpickles technicalpickles commented Aug 11, 2023

caller is pretty well known to be slow, since it has to navigate the stack among other things.

notify uses notify? as a guard clause inside it, but by the time it exits early, caller has already gotten the stack trace. This PR checks notify? at the callsites of notify instead, so that caller won't run unless notifications are going to go out.

I found this while using memory_profiler on some of my slow system specs. Here's some choice lines from the report:

allocated memory by gem
-----------------------------------
 343031719  isolator-0.9.0

 allocated memory by location
-----------------------------------
 271484591  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
  68927704  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

allocated objects by gem
-----------------------------------
   1252359  isolator-0.9.0

allocated objects by location
-----------------------------------
    964359  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
    224760  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

Allocated String Report
-----------------------------------
    412744  "/Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rspec-core-3.12.2/lib/rspec/core/example.rb:457:in `instance_exec'"
    169694  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
     26730  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

(there's several other strings that appear in stacks)

With this proposed change, isolator doesn't even show up in the memory_profiler report. To get a sense of the scope, for this one system spec, here's the before summary:

Total allocated: 5_363_399_946 bytes (45_328_676 objects)
Total retained:  180_774_831 bytes (1244196 objects)

and after:

Total allocated: 4_952_938_614 bytes (44_071_711 objects)
Total retained:  169_454_163 bytes (1116050 objects)

That's 410,461,332 less allocated memory (7.6% reduction), 1,256,965 less allocated objects (2.7% reduction), 11,320,668 less retained memory (6.2% reduction), and 128,146 less retained logics (10% reduction).

What is the purpose of this pull request?

What changes did you make? (overview)

Is there anything you'd like reviewers to focus on?

Checklist

  • I've added tests for this change
  • I've added a Changelog entry
  • I've updated a documentation

`caller` is pretty well known to be slow, since it has to navigate the
stack among other things.

`notify` uses `notify?` as a guard clause inside it, but by the time
it exits early, `caller` has already gotten the stack trace. This PR
checks `notify?` at the callsites of `notify` instead, so that
`caller` won't run unless notifications are going to go out.

I found this while using memory_profiler on some of my slow system
specs. Here's some choice lines from the report:

```
allocated memory by gem
-----------------------------------
 343031719  isolator-0.9.0

 allocated memory by location
-----------------------------------
 271484591  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
  68927704  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

allocated objects by gem
-----------------------------------
   1252359  isolator-0.9.0

allocated objects by location
-----------------------------------
    964359  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
    224760  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

Allocated String Report
-----------------------------------
    412744  "/Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rspec-core-3.12.2/lib/rspec/core/example.rb:457:in `instance_exec'"
    169694  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapters/http/webmock.rb:10
     26730  /Users/josh.nichols/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/isolator-0.9.0/lib/isolator/adapter_builder.rb:36

(there's several other strings that appear in stacks)
```

With this proposed change, isolator doesn't even show up in the
memory_profiler report. To get a sense of the scope, for this one system
spec, here's the before summary:

```
Total allocated: 5_363_399_946 bytes (45_328_676 objects)
Total retained:  180_774_831 bytes (1244196 objects)
```

and after:

```
Total allocated: 4_952_938_614 bytes (44_071_711 objects)
Total retained:  169_454_163 bytes (1116050 objects)
```

That's 410,461,332 less allocated memory (7.6% reduction), 1,256,965
less allocated objects (2.7% reduction), 11,320,668 less retained memory
(6.2% reduction), and 128,146 less retained logics (10% reduction).
@palkan palkan merged commit af8f56a into palkan:master Aug 16, 2023
7 checks passed
@palkan
Copy link
Owner

palkan commented Aug 16, 2023

Thanks!

@technicalpickles technicalpickles deleted the check-notify-before-using-caller branch August 16, 2023 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants