Florian Oswald
Florian Oswald

Reputation: 5134

what's the fastest way to reset a julia array to all zeros?

suppose I have an existing array like

x = rand(4)

and then I want to reset x to zero. Can I avoid doing x = zeros(4). I'm concerened about memory allocation.

Upvotes: 11

Views: 6523

Answers (3)

Chris Rackauckas
Chris Rackauckas

Reputation: 19132

The best way to do it in one line is:

x .= zero(y)

or

fill!(x, zero(y))

where y is the type of number you want it to be like. The reason why this way is good is that it works in all cases. If x is any type, using this will work as long as y matches the type (indeed, you can use y = x[1]).

When I mean any type, I mean that this also works for odd number types like SIUnits. If you use this command, a package could support SIUnits without ever having to import the package since this will apply the correct units to the x values (as long as all of its operations are correct in units), while fill!(x, 0.0) will error due to wrong units (you can also use fill!(x, zeros(y)). Otherwise, you'd have to check for units and all sorts of things.

Upvotes: 15

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22225

It seems to me people have suggested nice alternative ways of doing this but no-one addressed the actual question of "what's the most efficient way (specifically in terms of memory)".

So here it is. Given:

f1(x) = x    = zeros(size(x));
f2(x) = x[:] = zero(x[1]);
f3(x) = fill!(x, zero(x[1]));
f4(x) = x    = zero(x);

We have:

julia> x=rand(1000,1000); @time (for i in 1_000_000_000; x=f1(x); end;)
  0.000715 seconds (3 allocations: 7.629 MB)

julia> x=rand(1000,1000); @time (for i in 1_000_000_000; f2(x); end;)
  0.000691 seconds (2 allocations: 32 bytes)

julia> x=rand(1000,1000); @time (for i in 1_000_000_000; f3(x); end;)
  0.000702 seconds (2 allocations: 32 bytes)

julia> x=rand(1000,1000); @time (for i in 1_000_000_000; x=f4(x); end;)
  0.000704 seconds (2 allocations: 7.629 MB)


PS. As a response to some comments below, the comparison of the above methods is purely intended to demonstrate the difference in approaches quantitatively rather than in generic abstract terms, so as to more fully address the question of "what's more efficient, by how much" etc.
It is not intended to imply that f1 or f4 are mutating functions; they are not, they return a reference to a new object in memory; i.e. they are there for completeness to demonstrate the bad alternatives that OP is presumably trying to avoid.

I just felt that a question about "efficiency" deserved some numbers to complement the suggestions offered by my colleagues :)

Upvotes: 2

David P. Sanders
David P. Sanders

Reputation: 5325

You can do

fill!(x, 0.0)

This overwrites the contents with zeros.

This should be just as efficient as just doing a for loop, though:

for i in 1:length(x)
    x[i] = 0.0
end

Indeed, if you do @edit fill!(x, 0.0), you will see that this is basically what it is doing (except that it uses @inbounds for more efficiency).

Upvotes: 3

Related Questions