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

Inline singleton splats #36169

Closed
wants to merge 1 commit into from
Closed

Inline singleton splats #36169

wants to merge 1 commit into from

Commits on Jun 6, 2020

  1. Inline singleton splats

    As noted in #36087 and #29114, splatting integers currently has a
    performance penalty that is unexpected. For tuples and SimpleVectors,
    we have special purpose inliners that will simply inline the
    tuple/SimpleVector into the call being splatted. However, for
    everything else we'd have to run the iteration protocol to find
    out what the values to substitute are. This change does just that,
    limited to the case of length-1 (and empty) iterables. Benchmark:
    
    ```
    f(x) = (x...,)
    @code_typed f(1)
    @benchmark f(1)
    ```
    
    Before:
    ```
    julia> @code_typed f(1)
    CodeInfo(
    1 ─ %1 = Core._apply_iterate(Base.iterate, Core.tuple, x)::Tuple{Int64}
    └──      return %1
    ) => Tuple{Int64}
    
    julia> @benchmark f(1)
    BenchmarkTools.Trial:
      memory estimate:  32 bytes
      allocs estimate:  2
      --------------
      minimum time:     209.357 ns (0.00% GC)
      median time:      213.404 ns (0.00% GC)
      mean time:        218.674 ns (0.16% GC)
      maximum time:     1.922 μs (0.00% GC)
      --------------
      samples:          10000
      evals/sample:     540
    ```
    
    After:
    ```
    julia> @code_typed f(1)
    CodeInfo(
    1 ─ %1 = invoke Base.iterate(_2::Int64)::Tuple{Int64,Nothing}
    │   %2 = (getfield)(%1, 1)::Int64
    │   %3 = (getfield)(%1, 2)::Nothing
    │        invoke Base.iterate(_2::Int64, %3::Nothing)::Nothing
    │   %5 = Core.tuple(%2)::Tuple{Int64}
    └──      return %5
    ) => Tuple{Int64}
    
    julia> @benchmark f(1)
    BenchmarkTools.Trial:
      memory estimate:  0 bytes
      allocs estimate:  0
      --------------
      minimum time:     3.044 ns (0.00% GC)
      median time:      3.047 ns (0.00% GC)
      mean time:        3.049 ns (0.00% GC)
      maximum time:     7.700 ns (0.00% GC)
      --------------
      samples:          10000
      evals/sample:     1000
    ```
    
    Obviously this isn't 100% optimal yet, because the `iterate` calls themselves
    don't get inlined, but it's a lot better. Inlining the `iterate` calls is
    left for a follow up commit.
    Keno committed Jun 6, 2020
    Configuration menu
    Copy the full SHA
    0eb1f0f View commit details
    Browse the repository at this point in the history