Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: filtering an array with filter vs. for each

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 enter image description here

This is the memory used by the second solution enter image description here

like image 613
Gaglia88 Avatar asked Nov 21 '19 10:11

Gaglia88


1 Answers

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.

like image 190
Tim Avatar answered Sep 29 '22 21:09

Tim