Производительность для понимания в scala
У меня вопрос об эффективности for-comprehensions в scala.
Этот следующий код занимает около 45 секунд для запуска, когда perm является списком около 550 элементов
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}
Когда я изменил следующий код на следующий, он запустил за 3 секунды с тем же списком Perm
perm = some list
for{
perm <- perms.withFilter(_.size > 0)
word <- somefunction(perm) //expensive operation
sentence <- somefunction1(perm) //very expensive operation
} yield { word::sentence}
Разница в производительности имеет отношение к ленивой оценке в Scala?
Ответы
Ответ 1
Пусть обезвреживают оба понятия:
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
}
}
}
В первом случае обе дорогие функции будут выполняться каждый раз. Во втором случае, когда somefunction(perm)
возвращает пустой результат, somefunction1(perm)
никогда не будет выполнен.
Ответ 2
В вашем первом фрагменте, кажется, вы "зацикливаетесь" на каждом элементе, который у вас есть в вашей переменной, с каждым элементом в списке слов; По сути, декартово произведение.
Однако во втором фрагменте вы только "зацикливаете" каждый элемент в perm с одним "словом". Итак, я предполагаю, что это будет намного быстрее?
Кажется, я не могу разобрать все типы переменных, поэтому его довольно сложно полностью объяснить.