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?
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.
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