asif
asif

Reputation: 51

Is there any way to replace nested For loop with Higher order methods in scala

I am having a mutableList and want to take sum of all of its rows and replacing its rows with some other values based on some criteria. Code below is working fine for me but i want to ask is there any way to get rid of nested for loops as for loops slows down the performance. I want to use scala higher order methods instead of nested for loop. I tried flodLeft() higher order method to replace single for loop but can not implement to replace nested for loop

def func(nVect : Int , nDim : Int) : Unit = {
  var Vector = MutableList.fill(nVect,nDimn)(math.random)
  var V1Res =0.0
  var V2Res =0.0
  var V3Res =0.0
  for(i<- 0 to nVect -1) {
    for (j <- i +1 to nVect -1) {
      var resultant = Vector(i).zip(Vector(j)).map{case (x,y) => x + y}

      V1Res = choice(Vector(i))
      V2Res = choice(Vector(j))
      V3Res = choice(resultant)
      if(V3Res > V1Res){
       Vector(i) = res
      }
      if(V3Res > V2Res){
        Vector(j) = res
      }
    }
  }
}

Upvotes: 0

Views: 222

Answers (1)

Tim
Tim

Reputation: 27356

There are no "for loops" in this code; the for statements are already converted to foreach calls by the compiler, so it is already using higher-order methods. These foreach calls could be written out explicitly, but it would make no difference to the performance.


Making the code compile and then cleaning it up gives this:

def func(nVect: Int, nDim: Int): Unit = {
  val vector = Array.fill(nVect, nDim)(math.random)

  for {
    i <- 0 until nVect
    j <- i + 1 until nVect
  } {
    val res = vector(i).zip(vector(j)).map { case (x, y) => x + y }

    val v1Res = choice(vector(i))
    val v2Res = choice(vector(j))
    val v3Res = choice(res)

    if (v3Res > v1Res) {
      vector(i) = res
    }
    if (v3Res > v2Res) {
      vector(j) = res
    }
  }
}

Note that using a single for does not make any difference to the result, it just looks better!

At this point it gets difficult to make further improvements. The only parallelism possible is with the inner map call, but vectorising this is almost certainly a better option. If choice is expensive then the results could be cached, but this cache needs to be updated when vector is updated.

If the choice could be done in a second pass after all the cross-sums have been calculated then it would be much more parallelisable, but clearly that would also change the results.

Upvotes: 1

Related Questions