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

sizehint! + push! about 10x slower than resize! + indexing #32497

Closed
tkluck opened this issue Jul 4, 2019 · 3 comments
Closed

sizehint! + push! about 10x slower than resize! + indexing #32497

tkluck opened this issue Jul 4, 2019 · 3 comments

Comments

@tkluck
Copy link
Contributor

tkluck commented Jul 4, 2019

I'm trying to use sizehint! + push! to fill an array, but it is much slower than the equivalent operation using resize! and indexing. Benchmarks below.

I'm not surprised there's some overhead, and I'd be willing to accept some just to avoid potential bugs resulting from uninitialized data, but the overhead is 10x:

julia> VERSION
v"1.3.0-DEV.377"

julia> f!(arr, N) = ( sizehint!(arr, N); for i in 1:N; push!(arr, i); end; arr )
f! (generic function with 1 method)

julia> g!(arr, N) = ( resize!(arr, N); for i in 1:N; arr[i] = i; end; arr )
g! (generic function with 1 method)

julia> f!(Int[], 1_000_000) == g!(Int[], 1_000_000)
true

julia> @benchmark f!(arr, 1_000_000) setup=(arr=Int[])
BenchmarkTools.Trial: 
  memory estimate:  7.63 MiB
  allocs estimate:  1
  --------------
  minimum time:     3.717 ms (0.00% GC)
  median time:      3.811 ms (0.00% GC)
  mean time:        3.870 ms (0.00% GC)
  maximum time:     6.022 ms (0.00% GC)
  --------------
  samples:          1271
  evals/sample:     1

julia> @benchmark g!(arr, 1_000_000) setup=(arr=Int[])
BenchmarkTools.Trial: 
  memory estimate:  7.63 MiB
  allocs estimate:  1
  --------------
  minimum time:     392.328 μs (0.00% GC)
  median time:      419.459 μs (0.00% GC)
  mean time:        433.387 μs (0.00% GC)
  maximum time:     2.653 ms (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1

Almost all time is spent in the function _growend!, which in turn is backed by a C function so I can't easily pin-point on what line the slowness is. I have reproduced this in v1.0.3 as well as latest master.

@nalimilan
Copy link
Member

Probably a duplicate of #24909.

@tkluck
Copy link
Contributor Author

tkluck commented Jul 4, 2019

Replying to my own issue -- I'm not sure I should expect better performance than this. Even in the case of f!, only 3ns are spent for every push! call. The difference in performance may just be explainable by loop optimizations available in g!. There's a few v- operations in the code_native output (vpbroadcastq, vmovdqu) so that's reasonable.

I'll close this issue in a few days unless I find something useful.

@tkluck
Copy link
Contributor Author

tkluck commented Jul 4, 2019

Thanks @nalimilan! Going to close this issue so as not to disturb others.

@tkluck tkluck closed this as completed Jul 4, 2019
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

No branches or pull requests

2 participants