Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of for-comprehension in scala

I've a question about the efficiency of for-comprehensions in scala.

This following code takes around 45 sec to run when perm is a list of around 550 elements

perm = some list
for{
   perm <- perms.withFilter(_.size > 0)
   wordList = somefunction(perm) //expensive operation, wordlist is a list of strings
   sentenceList = somefunction1(perm) //very expensive operation, sentenceList is a list of list of strings
   word <- wordList
   sentence <- sentenceList
} yield { word::sentence}

When I changed the following code into the following, it ran in 3 sec with the same perm list

perm = some list
for{
   perm <- perms.withFilter(_.size > 0)
   word <- somefunction(perm) //expensive operation
   sentence <- somefunction1(perm) //very expensive operation
} yield { word::sentence}

Does the difference in the performance has something to do with lazy evaluation in Scala?

like image 221
Piyush Avatar asked Nov 03 '14 08:11

Piyush


1 Answers

Let's desugar both for-comprehensions:

1.)

perms.withFilter(_.size > 0).flatMap { perm =>
  val wordList = somefunction(perm) //expensive operation
  val sentenceList = somefunction1(perm) //very expensive operation
  wordList.flatMap { word =>
    sentenceList.map { sentence =>
      word::sentence
    }
  }
}

2.)

perms.withFilter(_.size > 0).flatMap { perm =>
  somefunction(perm).flatMap { word =>
    somefunction1(perm).map { sentence =>
      word :: sentence
    }
  }
}

In the first case, both expensive functions will be executed every time. In the second case, when somefunction(perm) returns an empty result, somefunction1(perm) will never be executed.

like image 150
drexin Avatar answered Oct 19 '22 02:10

drexin