Scala - aggregate 与 foldLeft 的性能比较
Scala - performance comparison of aggregate vs foldLeft
我的理解是 /: 与 foldLeft 相同,并且如果使用 'par' 将列表转换为并行集合,则聚合是 foldLeft 的更快版本。如果我是正确的,为什么以下代码显示 :/ 和 foldLeft 比列表中 'par' 使用的聚合更快。
我正在计算一个大列表的元素总和和元素数量,并将结果存储在元组 [Double,Double] 中。
//initial tuple2 (sum,count)
val tsc:Tuple2[Double,Double] = Tuple2(0.0,0.0)
//create a large list
val largeList = List.tabulate(500000)(n=>n*n)
//note time
val time1 = System.currentTimeMillis
//using aggregate without par
largeList.aggregate(tsc) ((tsc,elem) => (tsc._1+elem, tsc._2+1), (tsc1, tsc2)=>((tsc1._1+tsc2._1), (tsc1._2+tsc2._2)))
//note time
val time2 = System.currentTimeMillis
//use aggregate with par
largeList.par.aggregate(tsc) ((tsc,elem) => (tsc._1+elem, tsc._2+1), (tsc1, tsc2)=>((tsc1._1+tsc2._1), (tsc1._2+tsc2._2)))
//note time
val time3 = System.currentTimeMillis
//use /:
(tsc /: largeList)((tsc,elem)=>(tsc._1+elem, tsc._2+1))
//note time
val time4 = System.currentTimeMillis
//use foldLeft
largeList.foldLeft(tsc)((tsc,elem)=>(tsc._1+elem, tsc._2+1))
//note time
val time5 = System.currentTimeMillis
//calcualte time difference
println ("Time without par (millisecond)"+(time2-time1))
println ("Time with par (millisecond)"+(time3-time2))
println ("Time with /: (millisecond)"+(time4-time3))
println ("Time with FoldLeft (millisecond)"+(time5-time4)
我得到了以下结果
第 1 天的结果 运行
Time without par (millisecond)1198
Time with par (millisecond)1479
Time with /: (millisecond)626
Time with FoldLeft (millisecond)661
第 2 个结果 运行
Time without par (millisecond)703
Time with par (millisecond)581
Time with /: (millisecond)435
Time with FoldLeft (millisecond)423
我 运行 在 windows 10 中使用 cmd 进行此操作。 /: 和 FoldLeft 在性能上看起来相似,并且比聚合要好得多。在 1st 运行 中,使用 par 进行聚合实际上更耗时。这可能是由于 window 中的 'cmd'(控制台)无法利用多线程(这里只是猜测)
几个问题。您的数据集确实很小(因此并行化和线程管理的开销很大)。使用 List
意味着聚合的合并步骤是 O(N) - 一旦增加数据集大小,这似乎是最重要的因素。
切换到 Vector
并使用 10 倍大的 Vector,我得到:
Time without par (millisecond)271
Time with par (millisecond)297
Time with /: (millisecond)216
Time with FoldLeft (millisecond)274
这没那么戏剧化。我只是在 Scala 工作表中做了一个 运行,所以看到这些数字有很多变化
(我只有一个双核系统,所以看起来并行化的开销与收益相比是显着的)
我的理解是 /: 与 foldLeft 相同,并且如果使用 'par' 将列表转换为并行集合,则聚合是 foldLeft 的更快版本。如果我是正确的,为什么以下代码显示 :/ 和 foldLeft 比列表中 'par' 使用的聚合更快。
我正在计算一个大列表的元素总和和元素数量,并将结果存储在元组 [Double,Double] 中。
//initial tuple2 (sum,count)
val tsc:Tuple2[Double,Double] = Tuple2(0.0,0.0)
//create a large list
val largeList = List.tabulate(500000)(n=>n*n)
//note time
val time1 = System.currentTimeMillis
//using aggregate without par
largeList.aggregate(tsc) ((tsc,elem) => (tsc._1+elem, tsc._2+1), (tsc1, tsc2)=>((tsc1._1+tsc2._1), (tsc1._2+tsc2._2)))
//note time
val time2 = System.currentTimeMillis
//use aggregate with par
largeList.par.aggregate(tsc) ((tsc,elem) => (tsc._1+elem, tsc._2+1), (tsc1, tsc2)=>((tsc1._1+tsc2._1), (tsc1._2+tsc2._2)))
//note time
val time3 = System.currentTimeMillis
//use /:
(tsc /: largeList)((tsc,elem)=>(tsc._1+elem, tsc._2+1))
//note time
val time4 = System.currentTimeMillis
//use foldLeft
largeList.foldLeft(tsc)((tsc,elem)=>(tsc._1+elem, tsc._2+1))
//note time
val time5 = System.currentTimeMillis
//calcualte time difference
println ("Time without par (millisecond)"+(time2-time1))
println ("Time with par (millisecond)"+(time3-time2))
println ("Time with /: (millisecond)"+(time4-time3))
println ("Time with FoldLeft (millisecond)"+(time5-time4)
我得到了以下结果
第 1 天的结果 运行
Time without par (millisecond)1198
Time with par (millisecond)1479
Time with /: (millisecond)626
Time with FoldLeft (millisecond)661
第 2 个结果 运行
Time without par (millisecond)703
Time with par (millisecond)581
Time with /: (millisecond)435
Time with FoldLeft (millisecond)423
我 运行 在 windows 10 中使用 cmd 进行此操作。 /: 和 FoldLeft 在性能上看起来相似,并且比聚合要好得多。在 1st 运行 中,使用 par 进行聚合实际上更耗时。这可能是由于 window 中的 'cmd'(控制台)无法利用多线程(这里只是猜测)
几个问题。您的数据集确实很小(因此并行化和线程管理的开销很大)。使用 List
意味着聚合的合并步骤是 O(N) - 一旦增加数据集大小,这似乎是最重要的因素。
切换到 Vector
并使用 10 倍大的 Vector,我得到:
Time without par (millisecond)271
Time with par (millisecond)297
Time with /: (millisecond)216
Time with FoldLeft (millisecond)274
这没那么戏剧化。我只是在 Scala 工作表中做了一个 运行,所以看到这些数字有很多变化
(我只有一个双核系统,所以看起来并行化的开销与收益相比是显着的)