這是什麼,我現在在做什麼:檢查Scala集中所有'Seq'元素的大小是否爲1的最快方法是什麼?
val foo = Set[Seq[Int]](Seq(1), Seq(2), Seq(3))
val isAllSizeOne = foo.foldLeft(true) { case (agg, curr) => agg && curr.size == 1}
我能得到任何速度比這個?
這是什麼,我現在在做什麼:檢查Scala集中所有'Seq'元素的大小是否爲1的最快方法是什麼?
val foo = Set[Seq[Int]](Seq(1), Seq(2), Seq(3))
val isAllSizeOne = foo.foldLeft(true) { case (agg, curr) => agg && curr.size == 1}
我能得到任何速度比這個?
最簡潔的版本:
val isAllSizeOne = foo.forall(_.size == 1)
另一種替代方案,可能更快,但不夠簡明:
val isAllSizeOne = foo.forall(_.lengthCompare(1) == 0)
方法forall
旨在完全按照您的要求進行操作。
foo.forall(_.size == 1)
在大多數情況下,它將是您可以找到的最快的實施。與往常一樣,如果它非常重要,您應該嘗試對備選方案進行基準測試和/或分析,並瞭解最快的可能取決於您使用的是哪個集合。
對於非常大的集合,身價也考慮使用par
一個並行化版本,像這樣的實例,
foo.par.forall(_.size == 1)
大小操作需要通過在序列中的所有元素循環,另一種方法是:
foo.forall(l => l.nonEmpty && l.tail.isEmpty)
雖然序列的考慮尺寸小,它並沒有太大的差別。
壞主意!對於大多數'Seq's(保存列表,這是默認的實現),'tail'將創建一個新的集合!如果它是不可變的,它可能不是非常昂貴,但它肯定比計算元素更昂貴。如果您真的確信您的「尾部」操作便宜(例如,您是'LinearSeqLike'),則只能這樣做。 –
特別是'lengthCompare'對於像List這樣不知道自己的大小的序列來說很快,因爲它可以提早解救出來,而不是在找到多於一個元素時計算所有東西。對於知道自己長度的序列,它需要額外的邏輯,希望JVM最終能夠優化。 (通常根據我的經驗,至少在使用頻繁的代碼路徑中,這是我關心的代碼路徑。) –