File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -556,9 +556,7 @@ class Timer {
556556 }
557557
558558 func sort (compare_function = null) {
559- let length = @ length
560- let i = 0
561- let had_swaps = true
559+ const length = @ length
562560
563561 if length <= 1 {
564562 return self
@@ -568,24 +566,85 @@ class Timer {
568566 compare_function = -> (left, right) left <=> right
569567 }
570568
571- while (had_swaps) {
572- i = 0
573- had_swaps = false
569+ // secondary buffer, same size
570+ let buffer = self .sublist (0 , length)
574571
575- if @ length != length {
576- throw "List size changed during sort"
577- }
572+ // we alternate between these on each pass
573+ let src = self
574+ let dst = buffer
575+
576+ let width = 1
577+ while (width < length) {
578+ let i = 0
579+
580+ while (i < length) {
581+ let left = i
582+ let mid = i + width
583+ let right = i + width * 2
584+
585+ if mid > length {
586+ mid = length
587+ }
588+ if right > length {
589+ right = length
590+ }
591+
592+ // if there's no right run, just copy the tail
593+ if mid >= right {
594+ let t = left
595+ while (t < right) {
596+ dst[t] = src[t]
597+ t += 1
598+ }
599+ i = right
600+ continue
601+ }
578602
579- @ each (-> (value, index) {
580- if index < length - 1 {
581- const next_value = self [index + 1 ]
582- if compare_function (value, next_value) > 0 {
583- self [index] = next_value
584- self [index + 1 ] = value
585- had_swaps = true
603+ let a = left
604+ let b = mid
605+ let k = left
606+
607+ while (a < mid && b < right) {
608+ if compare_function (src[a], src[b]) <= 0 {
609+ dst[k] = src[a]
610+ a += 1
611+ } else {
612+ dst[k] = src[b]
613+ b += 1
586614 }
615+ k += 1
616+ }
617+
618+ while (a < mid) {
619+ dst[k] = src[a]
620+ a += 1
621+ k += 1
587622 }
588- })
623+
624+ while (b < right) {
625+ dst[k] = src[b]
626+ b += 1
627+ k += 1
628+ }
629+
630+ i = right
631+ }
632+
633+ // next pass: swap roles
634+ let tmp = src
635+ src = dst
636+ dst = tmp
637+
638+ width = width * 2
639+ }
640+
641+ // if final result ended up in buffer, copy back once
642+ if src != self {
643+ let i = 0
644+ while (i < length) {
645+ self [i] = src[i]
646+ i += 1
647+ }
589648 }
590649
591650 self
You can’t perform that action at this time.
0 commit comments