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

Extra allocation when modifying arrays #14939

Closed
samuel-massinon opened this issue Feb 4, 2016 · 8 comments
Closed

Extra allocation when modifying arrays #14939

samuel-massinon opened this issue Feb 4, 2016 · 8 comments

Comments

@samuel-massinon
Copy link
Contributor

I notice this that doing simply operations on an array can allocate a lot of memory when I don't think it would need to. For example:

julia> function foo(a::AbstractArray, value::Int)
           for i in 1:length(a)
               a[i] += value
           end
       end
foo (generic function with 1 method)

julia> len = 100000000; a = collect(1:len);

julia> foo(a, 20); #compile

julia> @time foo(a, 20);
  0.116317 seconds (4 allocations: 160 bytes)

julia> @time a[:] += 20;
  1.871425 seconds (13 allocations: 1.490 GB, 6.84% gc time)

julia> @time a += 20;
  0.542140 seconds (8 allocations: 762.940 MB, 0.33% gc time)

julia> @time a + 20;
  1.095872 seconds (8 allocations: 762.940 MB, 7.90% gc time)

From the example above, foo,(a, 20), a[:] += 20, and a += 20 are all doing the same thing, but my foo function is much faster and takes a fraction of the allocated memory.

Should julia's memory management be able to identify those cases and avoid the extra allocation?

@StefanKarpinski
Copy link
Member

Please post questions like this that aren't clear-cut bugs on julia-users.

@JeffBezanson
Copy link
Member

a += 20 is expanded to a = a+20, so it actually does not modify the array in place. Other than that, yes, we would love to improve performance here.

@StefanKarpinski
Copy link
Member

To answer your question x += y is always syntactic sugar for x = x + y. So a[:] += 20 means a[:] = a[:] + 20; the RHS is a new array which is allocated and its contents are then copied to the original a. a += 2 means a = a + 20; the RHS is a new array, which the name a is then bound to, leaving the original array a was bound to unchanged. a + 20 allocates a new array.

@StefanKarpinski
Copy link
Member

Obviously there are situations like a[:] += 20 where allocation can always be avoided, but that's an optimization we haven't yet gotten around to, as @JeffBezanson alluded to. Some of the other expressions can also be optimized sometimes – they are harder though because there are cases where the optimization is not safe to perform.

@JeffBezanson
Copy link
Member

See also #3424

@samuel-massinon
Copy link
Contributor Author

@StefanKarpinski Sorry! Will remember for next time.

Why these operations were doing this made sense to me, I just see opportunity to improve on it. :)

Thanks for your replies!

@StefanKarpinski
Copy link
Member

No worries! Glad it makes sense. There's definitely ample room for improvement.

@stevengj
Copy link
Member

stevengj commented Feb 4, 2016

Closing as a duplicater of #249, JuliaLang/LinearAlgebra.jl#119, etc.

@stevengj stevengj closed this as completed Feb 4, 2016
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

4 participants