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 extra allocation in String#from and #to #36180

Merged
merged 1 commit into from Jul 26, 2019

Conversation

jonathanhefner
Copy link
Member

@jonathanhefner jonathanhefner commented May 4, 2019

Removes unnecessary Range object allocations for a significant speed-up.

String#from Comparison:
  new:   3378594.0 i/s
  old:   2380129.8 i/s - 1.42x slower

String#to Comparison:
  new:   2866175.7 i/s
  old:   2304406.4 i/s - 1.24x slower

@kamipo
Copy link
Member

kamipo commented May 5, 2019

Can you improve String#to to allocate no range object as well?

Removes unnecessary Range object allocations for a significant speed-up.

String#from Comparison:
  new:   3378594.0 i/s
  old:   2380129.8 i/s - 1.42x slower

String#to Comparison:
  new:   2866175.7 i/s
  old:   2304406.4 i/s - 1.24x slower
@jonathanhefner jonathanhefner changed the title Avoid extra object allocation in String#from Avoid extra allocation in String#from and #to May 5, 2019
@jonathanhefner
Copy link
Member Author

@kamipo Done!

@rafaelfranca rafaelfranca merged commit 4d6bbf0 into rails:master Jul 26, 2019
@@ -61,7 +61,8 @@ def from(position)
# str.from(0).to(-1) # => "hello"
# str.from(1).to(-2) # => "ell"
def to(position)
self[0..position]
position = [position + length, -1].max if position < 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious what the -1 and max here is for? I could get all tests to pass with: position += size if position < 0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose the condition does not preserve the original behavior, or hard to understand what this do.
Maybe we should more exercise that in tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is for when position + length is less than -1.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafaelfranca Yes, exactly.

For example, "foo".to(-10) without the max becomes "foo"[0, -10 + 3 + 1] or "foo"[0, -6], which returns nil.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see! I found relying on -1 + 1 to get a 0 length for String#[] a little confusing, so I tried to change it a bit in efa2299 with extra tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaspth I had considered that variation, because it is a bit more clear. But, I decided to use max because the extra to_s makes it ~13% slower when the position isn't negative. Of course, it's only a micro-benchmark and likely of no consequence, but since the purpose of the PR was performance, that's what I went with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to fastest variant 71e41a5.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kamipo Excellent! 👍

jonathanhefner added a commit to jonathanhefner/casual_support that referenced this pull request Jan 31, 2020
These performance optimizations have been contributed to Active Support
in rails/rails#36180.
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

4 participants