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

Module#delegate avoid creating a unique fstring for each delegator #50698

Merged
merged 1 commit into from
Jan 10, 2024

Conversation

byroot
Copy link
Member

@byroot byroot commented Jan 10, 2024

For example:

delegate :negative?, to: :value, as: Numeric

Before:

def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError, "ActiveSupport::Duration#negative? delegated to @value.negative?, but @value is nil: #{self.inspect}"
  else
    raise
  end
end

After:

def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError.nil_target(:negative?, :"@value")
  else
    raise
  end
end

Before almost every delegator would generate a large unique string that gets interned for the error message that is rarely if ever used.

Rather than to "hardcode" a unique string, we now only pass pre-existing symbols to a method helper that will build the error message.

This alone saves about 160B per delegator, and the method bytecode is also marginally smaller (but it's harder to assess how much this actually saves)

For example:

```ruby
delegate :negative?, to: :value, as: Numeric
```

Before:

```
def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError, "ActiveSupport::Duration#negative? delegated to @value.negative?, but @value is nil: #{self.inspect}"
  else
    raise
  end
end
```

After:

```ruby
def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError.nil_target(:negative?, :"@value")
  else
    raise
  end
end
```

Before almost every delegator would generate a large unique string that gets interned for
the error message that is rarely if ever used.

Rather than to "hardcode" a unique string, we now only pass pre-existing symbols to
a method helper that will build the error message.

This alone saves about 160B per delegator, and the method bytecode is also marginally
smaller (but it's harder to assess how much this actually saves)
@byroot byroot merged commit b83827a into rails:main Jan 10, 2024
4 checks passed
@byroot byroot deleted the delegate-reduce-fstring branch January 10, 2024 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants