I have this problem: I want to iterate on the elements of an array that satisfy a certain condition.
The first thing I though is to use the filter method on the original array and then iterates over the resulting elements. But I had some memory usage problem with that, i.e. java heap space. When a filter is applied on an array, it will instantiate a new array? So it will copy each element?
Is it better to use this approach:
array.filter(<condition>).foreach{ element =>
do something
}
Or the following one?
for(i <- array.indices if <condition>){
do something
}
Moreover, I wrote these two tests:
With for
val size = 10000000
val elements = Array.ofDim[Double](size)
for (i <- elements.indices) {
elements.update(i, math.random)
}
var cont = 0
val n = 0.5
while(true){
cont = 0
for (j <- elements.indices if elements(j) < n) {
cont += 1
}
println(cont)
}
with filter
val size = 10000000
val elements = Array.ofDim[Double](size)
for (i <- elements.indices) {
elements.update(i, math.random)
}
val n = 0.5
while(true){
val valid = elements.filter(x => x < n)
println(valid.size)
}
and I checked the memory usage with VisualVM, it seem that the first solution uses less memory than the second one.
This is the memory used by the first solution

This is the memory used by the second solution

The for expression use the withFilter method rather than filter, which avoids creating the intermediate Array. So either use the for version or use withFilter rather than filter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With