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