diff --git a/src/benchmark.nim b/src/benchmark.nim index a222ed8..028a955 100644 --- a/src/benchmark.nim +++ b/src/benchmark.nim @@ -40,7 +40,7 @@ randomize(42) echo &"Averaged over {Runs} runs\n" -for n in [10_000, 100_000, 1_000_000]: +for n in [1000, 10_000, 100_000, 1_000_000]: echo &"--- n = {n} ---" echo " [int32]" bench32(" std sort ", n, proc(a: var seq[int32]) = std.sort(a)) diff --git a/src/csort.nim b/src/csort.nim index b2a4d4f..fc5a636 100644 --- a/src/csort.nim +++ b/src/csort.nim @@ -297,13 +297,10 @@ proc cSortCore[T: int32 | int64](data: ptr UncheckedArray[T], n: int) = p = p shr 1 -proc cSortImpl[T: int32 | int64](items: var openArray[T]) = +proc sort*[T: int32 | int64](items: var openArray[T]) = if items.len < 2: return cSortCore(cast[ptr UncheckedArray[T]](addr items[0]), items.len) -proc sort*(items: var openArray[int32]) = cSortImpl(items) -proc sort*(items: var openArray[int64]) = cSortImpl(items) - proc sort*(items: var openArray[int]) = if items.len < 2: return when sizeof(int) == 4: @@ -314,21 +311,14 @@ proc sort*(items: var openArray[int]) = # Unsigned sort: XOR each element with the high bit to map [0..UINT_MAX] -> # [INT_MIN..INT_MAX] preserving order, sort as signed integers, then un-map. -proc sort*(items: var openArray[uint32]) = - let n = items.len - if n < 2: return - let idata = cast[ptr UncheckedArray[int32]](addr items[0]) - for i in 0 ..< n: idata[i] = idata[i] xor low(int32) - cSortCore(idata, n) - for i in 0 ..< n: idata[i] = idata[i] xor low(int32) - -proc sort*(items: var openArray[uint64]) = +proc sort*[T: uint32 | uint64](items: var openArray[T]) = + type iT = (when T is uint32: int32 else: int64) let n = items.len if n < 2: return - let idata = cast[ptr UncheckedArray[int64]](addr items[0]) - for i in 0 ..< n: idata[i] = idata[i] xor low(int64) + let idata = cast[ptr UncheckedArray[iT]](addr items[0]) + for i in 0 ..< n: idata[i] = idata[i] xor low(iT) cSortCore(idata, n) - for i in 0 ..< n: idata[i] = idata[i] xor low(int64) + for i in 0 ..< n: idata[i] = idata[i] xor low(iT) proc sort*(items: var openArray[uint]) = if items.len < 2: return @@ -347,18 +337,11 @@ proc sort*(items: var openArray[uint]) = # Float sort: transform bit-patterns to sort keys, sort as integers, untransform. # Resulting order: -NaN < -INF < ... < -0.0 < +0.0 < ... < +INF < +NaN -proc sort*(items: var openArray[float32]) = - let n = items.len - if n < 2: return - let idata = cast[ptr UncheckedArray[int32]](addr items[0]) - for i in 0 ..< n: idata[i] = floatSortKey(idata[i]) - cSortCore(idata, n) - for i in 0 ..< n: idata[i] = floatSortKey(idata[i]) - -proc sort*(items: var openArray[float64]) = +proc sort*[T: float32 | float64](items: var openArray[T]) = + type iT = (when T is float32: int32 else: int64) let n = items.len if n < 2: return - let idata = cast[ptr UncheckedArray[int64]](addr items[0]) + let idata = cast[ptr UncheckedArray[iT]](addr items[0]) for i in 0 ..< n: idata[i] = floatSortKey(idata[i]) cSortCore(idata, n) for i in 0 ..< n: idata[i] = floatSortKey(idata[i])