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

[Compatibility] Implement Time#deconstruct_keys #3409

Merged
merged 1 commit into from
Jan 30, 2024

Conversation

rwstauner
Copy link
Collaborator

I also tried it with a big case statement (instead of the hash/send)... it's about 10 lines longer, but they appear to bench about the same. 🤷
If you think that (or some other design) would be better let me know.

I updated the one spec because this deconstruct_keys handles unknown symbols differently than the one for MatchData.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Jan 25, 2024
@rwstauner rwstauner force-pushed the rwstauner/time-deconstruct-keys branch from 8d3b01a to a534cd6 Compare January 25, 2024 00:07
@andrykonchin
Copy link
Member

I also tried it with a big case statement (instead of the hash/send)... it's about 10 lines longer, but they appear to bench about the same. 🤷

It would be interesting to look at the benchmark results.

@eregon
Copy link
Member

eregon commented Jan 25, 2024

I also tried it with a big case statement (instead of the hash/send)... it's about 10 lines longer, but they appear to bench about the same. 🤷

The case should be much better.
The main reason is that public_send with 11 different method names will go megamorphic and that should be a lot slower.

(It would also be possible to do a mix between both approaches by having a constant Hash of Symbol to e.g. -> t { t.hour } and then use THAT_HASH[symbol].call. But that would be a megamorphic block call then which is not great either. So the straightforward case should be best)

@rwstauner
Copy link
Collaborator Author

It would be interesting to look at the benchmark results.

require "benchmark/ips"

t = Time.utc(2022, 10, 5, 13, 30)
res = { year: 2022, month: 10, day: 5, yday: 278, wday: 3, hour: 13,
        min: 30, sec: 0, subsec: 0, dst: false, zone: "UTC" }
slice = res.slice(:year, :month)
def assert_equal(x, y)
  raise "#{x}\n#{y}" unless x == y
end

Benchmark.ips do |x|
  x.report("hash") do
    assert_equal(t.deconstruct_keys(nil) , res)
    assert_equal(t.deconstruct_keys([:year, :month]) , slice)
    assert_equal(t.deconstruct_keys([:year, :month, :day, :yday, :wday, :hour, :min, :sec, :subsec, :dst, :zone]) , res)
  end
  x.report("case") do
    assert_equal(t.deconstruct_keys_case(nil) , res)
    assert_equal(t.deconstruct_keys_case([:year, :month]) , slice)
    assert_equal(t.deconstruct_keys_case([:year, :month, :day, :yday, :wday, :hour, :min, :sec, :subsec, :dst, :zone]) , res)
  end
end

# truffleruby 24.1.0-dev-740a6e18*, like ruby 3.2.2, Interpreted JVM [aarch64-darwin]
# Warming up --------------------------------------
#                 case     2.278k i/100ms
#                 hash     2.481k i/100ms
# Calculating -------------------------------------
#                 case     24.173k (± 1.1%) i/s -    123.012k in   5.089611s
#                 hash     25.475k (± 1.0%) i/s -    129.012k in   5.064732s

# truffleruby 24.1.0-dev-740a6e18*, like ruby 3.2.2, Interpreted JVM [aarch64-darwin]
# Warming up --------------------------------------
#                 case     2.436k i/100ms
#                 hash     2.450k i/100ms
# Calculating -------------------------------------
#                 case     24.485k (± 0.7%) i/s -    124.236k in   5.074140s
#                 hash     25.873k (± 1.1%) i/s -    129.850k in   5.019333s

# truffleruby 24.1.0-dev-740a6e18*, like ruby 3.2.2, Interpreted JVM [aarch64-darwin]
# Warming up --------------------------------------
#                 hash     2.519k i/100ms
#                 case     2.409k i/100ms
# Calculating -------------------------------------
#                 hash     25.325k (± 0.8%) i/s -    128.469k in   5.073215s
#                 case     24.145k (± 1.1%) i/s -    122.859k in   5.089007s

@rwstauner
Copy link
Collaborator Author

Thanks, I appreciate the insights!

@rwstauner rwstauner force-pushed the rwstauner/time-deconstruct-keys branch from a534cd6 to 5aeb599 Compare January 25, 2024 17:40
@eregon
Copy link
Member

eregon commented Jan 26, 2024

Interpreted JVM so that's the issue with that benchmark, it's only benchmarking the interpreter which has lots of other overhead.
Could you rerun it on the jvm-ce env?

@rwstauner
Copy link
Collaborator Author

Oops, thanks, I didn't realize I was running the jvm build.
With jvm-ce there is quite a difference, even if I make the methods hash a constant:

truffleruby 24.1.0-dev-740a6e18*, like ruby 3.2.2, GraalVM CE JVM [aarch64-darwin]
Warming up --------------------------------------
                case    31.541k i/100ms
                hash    52.239k i/100ms
Calculating -------------------------------------
                case      1.038M (± 3.2%) i/s -      5.204M in   5.020972s
                hash    584.887k (± 2.1%) i/s -      2.925M in   5.004034s

@rwstauner rwstauner force-pushed the rwstauner/time-deconstruct-keys branch from 5aeb599 to 956117e Compare January 26, 2024 17:29
@andrykonchin andrykonchin added the in-ci The PR is being tested in CI. Do not push new commits. label Jan 29, 2024
Comment on lines 273 to 276
when :year
ret[:year] = year
when :month
ret[:month] = month
Copy link
Member

Choose a reason for hiding this comment

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

The ret[:year] = etc could be moved out of the case like ret[key] = case key.
This avoids the duplication and significantly reduces the memory footprint and # of AST nodes for this method.
@andrykonchin Could you do it (since we have little time before the feature freeze)?

Copy link
Member

Choose a reason for hiding this comment

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

I am on it 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, that's a good catch!

@andrykonchin andrykonchin force-pushed the rwstauner/time-deconstruct-keys branch from 956117e to f4157c5 Compare January 29, 2024 14:01
@graalvmbot graalvmbot merged commit 42e6710 into oracle:master Jan 30, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in-ci The PR is being tested in CI. Do not push new commits. OCA Verified All contributors have signed the Oracle Contributor Agreement. shopify
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants