Mergesort.x10 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import x10.io.Console;
  2. import x10.util.Random;
  3. public class Mergesort {
  4. private static val rand = new Random();
  5. private static val MIN_ELEMENTS_PARALLEL = 65536;
  6. public static def sort(values : Array[Int](1)) : Array[Int](1) {
  7. val numbers = new Array[Int](values.size);
  8. val helper = new Array[Int](values.size);
  9. Array.copy(values, numbers);
  10. mergesort(0, values.size - 1, numbers, helper);
  11. return numbers;
  12. }
  13. private static def mergesort(low : Int, high : Int, numbers : Array[Int](1), helper : Array[Int](1)) {
  14. if (low < high) {
  15. val middle = (low + high) / 2;
  16. if (high - low >= MIN_ELEMENTS_PARALLEL) {
  17. finish {
  18. async mergesort(low, middle, numbers, helper);
  19. async mergesort(middle + 1, high, numbers, helper);
  20. }
  21. } else {
  22. mergesort(low, middle, numbers, helper);
  23. mergesort(middle + 1, high, numbers, helper);
  24. }
  25. merge(low, middle, high, numbers, helper);
  26. }
  27. }
  28. private static def merge(low : Int, middle : Int, high : Int, numbers : Array[Int](1), helper : Array[Int](1)) {
  29. // Copy the part to be merged into the helper (from low to high)
  30. Array.copy(numbers, low, helper, low, high - low + 1);
  31. var left : Int = low;
  32. var right : Int = middle + 1;
  33. var position : Int = low;
  34. while(left <= middle && right <= high) {
  35. if (helper(left) <= helper(right)) {
  36. numbers(position++) = helper(left++);
  37. } else {
  38. numbers(position++) = helper(right++);
  39. }
  40. }
  41. while(left <= middle) {
  42. numbers(position++) = helper(left++);
  43. }
  44. // Nothing needs to be done for the right half, because is still
  45. // is where it was copied from, which happens to be the right
  46. // location.
  47. }
  48. public static def main(args:Array[String](1)) {
  49. if (args.size < 1) {
  50. Console.OUT.println("Expect array length as argument");
  51. return;
  52. }
  53. val sort_count = Int.parse(args(0));
  54. val to_sort:Array[Int] = new Array[Int](sort_count, (_:Int) => { return rand.nextInt(); });
  55. for (i in to_sort) {
  56. Console.OUT.print(to_sort(i) + " ");
  57. }
  58. Console.OUT.println();
  59. val start = System.nanoTime();
  60. val sorted = sort(to_sort);
  61. val duration = System.nanoTime() - start;
  62. Console.OUT.println("Sorting took " + duration / 1000000.0 + "ms");
  63. Console.OUT.println("Checking for sortedness...");
  64. for (i in sorted) {
  65. Console.OUT.print(sorted(i) + " ");
  66. }
  67. Console.OUT.println();
  68. }
  69. }