Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation with broadcasted operation

Tags:

julia

I have a loop which goes upto 100000 and each time it finds the index of numbers matching a certain criteria.

x is an array of floats.

x = [0.1,0.3,-0.2, 0.4,0.0, 0.9,1.1]
for i = 1:n 
    cr = max(0.0, 0.2*sqrt(i) - 20)
    ftt = findall(x .<= cr)
    #I have other things here but they are not necessary
end

How can you avoid memory allocation by using findall in a loop?

like image 252
kkirui Avatar asked Feb 06 '26 09:02

kkirui


2 Answers

Since findall returns a variable sized array of indices, the way you've written this inherently involves allocation: that array of indices has to be allocated. If you're going to do something for each index, however, then you could use a loop instead, e.g.:

x = [0.1,0.3,-0.2, 0.4,0.0, 0.9,1.1]
for i = 1:n 
    cr = max(0.0, 0.2*sqrt(i) - 20)
    for (index, item) in enumerate(x)
        item <= cr || continue
        # do something with index, item
    end
end

This doesn't allocate memory because it operates on each index and item, one at a time instead of returning them all at once.

like image 103
StefanKarpinski Avatar answered Feb 09 '26 10:02

StefanKarpinski


The issue is that:

x .<= cr

creates a temporary boolean array the size of x.

To avoid that, you could use a comprehension (and enumerate() to yield the index along with the value):

[i for (i, x_i) in enumerate(x) if x_i <= cr]

or a generator (see @BogumiłKamiński comment):

(i for (i, x_i) in enumerate(x) if x_i <= cr)

depending on what you need to do with it afterwards.

like image 30
norok2 Avatar answered Feb 09 '26 10:02

norok2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!