Skip to content

Commit ca6b3ca

Browse files
committed
parallel merge sort in scala
1 parent edf8db5 commit ca6b3ca

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

oracle_sort/parMergeSort.scala

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import scala.annotation.tailrec
2+
import scala.util.Random
3+
import java.time.Duration
4+
import java.time.LocalDate
5+
import scala.concurrent._
6+
import ExecutionContext.Implicits.global
7+
import scala.util.{Success, Failure}
8+
import scala.concurrent.ExecutionContext
9+
import java.util.concurrent.Executors
10+
import scala.concurrent.duration._
11+
12+
def parMergeSort(list: List[Int], depth: Int = 0, max_depth: Int = 4): List[Int] = {
13+
@tailrec
14+
def merge(left: List[Int], right: List[Int], accumulator: List[Int] = List()): List[Int] = (left, right) match {
15+
case(left, Nil) => accumulator ++ left
16+
case(Nil, right) => accumulator ++ right
17+
case(leftHead :: leftTail, rightHead :: rightTail) =>
18+
if (leftHead < rightHead) merge(leftTail, right, accumulator :+ leftHead)
19+
else merge(left, rightTail, accumulator :+ rightHead)
20+
}
21+
22+
val n = list.length / 2
23+
if (n == 0) list
24+
else {
25+
val (left, right) = list.splitAt(n)
26+
27+
if( depth < max_depth) {
28+
val lf = Future { parMergeSort(left, depth + 1, max_depth) }
29+
val rf = Future { parMergeSort(right, depth + 1, max_depth) }
30+
31+
Await.result(lf, scala.concurrent.duration.Duration.Inf)
32+
Await.result(rf, scala.concurrent.duration.Duration.Inf)
33+
34+
merge( lf.value.orNull.get, rf.value.orNull.get )
35+
} else {
36+
merge( mergeSort(left), mergeSort(right) )
37+
}
38+
}
39+
}
40+
41+
val r = new Random()
42+
val list = (1 to 10000).map( _ => r.nextInt()).toList
43+
44+
//сверка правильности работы
45+
assert(parMergeSort(list,0,0) == list.sorted)
46+
assert(parMergeSort(list) == list.sorted)
47+
assert(parMergeSort(list,0,0) == parMergeSort(list))
48+
49+
//замер времени работы
50+
def calcMs(c: => Unit): Long = {
51+
val st_dt = java.time.LocalDateTime.now
52+
c
53+
Duration.between(st_dt, java.time.LocalDateTime.now).toMillis
54+
}
55+
56+
var res: List[(Int,Long)] = List()
57+
for(i <- 0 to 8; j <- 0 to 3) {
58+
res = res :+ (i, calcMs({
59+
parMergeSort(list,0,i)
60+
}) )
61+
}
62+
res.groupBy(_._1).mapValues(i => i.map(_._2).sum / i.map(_._2).count(_=>true)).toSeq.sortBy(_._2)
63+
//res74: Seq[(Int, Long)] = Vector((4,4534), (5,4599), (6,4608), (3,4610), (2,4657), (8,4691), (7,4702), (1,5073), (0,6697))
64+
//sequencial sort = 6697
65+
//parallel merge sort (4) == 4534

0 commit comments

Comments
 (0)