Celerity.Sorting 2.6.0

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Celerity.Sorting --version 2.6.0
                    
NuGet\Install-Package Celerity.Sorting -Version 2.6.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Celerity.Sorting" Version="2.6.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Celerity.Sorting" Version="2.6.0" />
                    
Directory.Packages.props
<PackageReference Include="Celerity.Sorting" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Celerity.Sorting --version 2.6.0
                    
#r "nuget: Celerity.Sorting, 2.6.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Celerity.Sorting@2.6.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Celerity.Sorting&version=2.6.0
                    
Install as a Cake Addin
#tool nuget:?package=Celerity.Sorting&version=2.6.0
                    
Install as a Cake Tool

Celerity.Sorting

Non-comparison sorts and selection over primitive keys. Part of the Celerity family of high-performance .NET libraries.

Array.Sort / MemoryExtensions.Sort<T> route through a scalar comparison introsort for primitive keys on every current runtime — there is no radix, counting, or selection path anywhere in the BCL. And the BCL structurally cannot add one: Array.Sort is contractually in-place, while a radix sort needs O(n) scratch. That is exactly the flexibility-for-speed trade Celerity exists to make.

What's in the box

  • RadixSort — LSD radix over uint / int / ulong / long / float / double: four (32-bit) or eight (64-bit) counting passes with purely sequential reads, no comparisons and no data-dependent branches. Keys alone, keys with a parallel payload, or ArgSort — an index permutation that ranks without moving a wide payload. Stable.
  • CountingSort — bounded key ranges (byte, ushort, or int over a declared [min, max]): one histogram pass and one run-fill, O(n + range), for the shape that enum ordinals, bucket ids and quantized scores take. The keys-only forms never move an element twice.
  • PartialSortSelect / Sort are an O(n) in-place introselect for the k smallest; TopK is an O(n log k) bounded heap over a read-only span.

RadixSort and CountingSort pair every entry point with a SortWithScratch twin that allocates nothing, so a hot loop supplies its buffers once instead of renting per call. (Sort is the convenience form and rents from ArrayPool<T>; the two names are kept apart so Sort(keys, values) always means key-and-payload, the way Array.Sort(keys, items) does.) PartialSort has no scratch overloads — it needs no scratch and allocates nothing in any form.

Where it wins, and where it does not

Celerity documents its tradeoffs rather than claiming a blanket win:

  • RadixSort loses below a few hundred elements — the fixed cost of the histogram pass dominates. Use Array.Sort for small spans; the crossover is a measured number on the benchmark dashboard, which sweeps from 100 to 1,000,000 elements precisely so it can be read off.
  • CountingSort loses once range approaches n — the histogram costs range no matter how few elements there are. Rule of thumb: range ≲ n.
  • PartialSort is not asymptotically better than LINQ. OrderBy().Take(k) has applied its own partial-sort optimization since .NET 6. The win is that this works on a span in place, allocates nothing, boxes no comparer, and materializes no intermediate sequence.

Two deliberate floating-point divergences

RadixSort orders float / double keys by their (transformed) bit pattern, so:

  • NaN keys sort by sign bit — sign-bit-set NaNs before every number, the rest after — where Array.Sort moves every NaN to the front.
  • -0.0 sorts before +0.0, where the BCL comparer calls them equal.

Filter or normalize NaNs first if you need the BCL's placement.

Quick start

dotnet add package Celerity.Sorting
using Celerity.Sorting;

// Ten million ids, sorted with four branch-free passes.
int[] ids = LoadIds();
RadixSort.Sort(ids.AsSpan());

// Sort ids and carry a parallel payload, allocating nothing in the hot loop.
int[] keyScratch = new int[ids.Length];
string[] valueScratch = new string[ids.Length];
RadixSort.SortWithScratch(ids.AsSpan(), names.AsSpan(), keyScratch, valueScratch);

// Rank without moving a wide payload.
int[] order = new int[ids.Length];
RadixSort.ArgSort(ids, order);

// The 10 worst offenders out of a million, without touching the source.
int[] worst = new int[10];
PartialSort.TopK<int>(latencies, worst);

See the sorting API reference for full docs and runnable examples.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.6.1-beta.2 0 8/10/2026
2.6.1-beta.1 33 8/9/2026
2.6.0 44 8/9/2026
2.5.1-beta.12 46 8/8/2026
2.5.1-beta.6 37 8/7/2026
2.5.1-beta.4 40 8/5/2026