Skip to content

Feature request: ordered/sorted collections (+ reminder: NextGen SIMD scanner not wired in) #157

Description

@Stemonik

Two small things from real use, bundled into one note. Happy to contribute both
via PR (same flow as #150 / #151) if you're open to it.

1) Collections: an ordered / sorted dictionary (and sorted set)

Dext.Collections already covers a lot — IList<T> (with Sort(comparer) +
BinarySearch), IDictionary<K,V>, IConcurrentDictionary<K,V>,
IFrozenDictionary<K,V>, IHashSet<T>, stack/queue. What's missing is a
dictionary/set that preserves an order as a first-class type. Two flavors,
both currently absent (grep on sorted/ordered/tree/skiplist is empty):

  • IOrderedDictionary<K,V> — .NET-style / LinkedHashMap: O(1) lookup +
    iteration in insertion order. This is the one we hit most: build an index
    over a result set, then both "does key X exist?" (O(1)) and "walk them in the
    order they came in" without a second sort.
  • ISortedDictionary<K,V> (tree/skiplist) — iteration/lookup in key order,
    O(log n). Plus the natural complement ISortedSet<T> (today only the
    unordered IHashSet<T> exists).

What we do not need (already covered): key-ordered iteration over a list is
IList.Sort + BinarySearch; O(1) membership is IDictionary.ContainsKey /
TryGetValue. Only the ordered/sorted dictionary/set as a type is the gap.

Our current bridge is a tiny TOrderedIndex<TKey,T> wrapper (a TList for order

  • an IDictionary for lookup). It works, but it'd be cleaner as a native Dext
    collection alongside the others. If useful, I can PR an IOrderedDictionary<K,V>
    (insertion-order, the higher-value one) first, then a sorted variant.

2) NextGen JSON — reminder: the SIMD scanner is still not wired in

Just a reminder, not a re-open. From the earlier benchmark note (reply26) + the
FindKey scalar PR (#151, merged — thanks): the SSE4.2 structural scanner
TNextGenJsonParser.ScanStructural_SSE42 is defined but never called — the
parser (ScanString / whitespace skipping) still runs fully scalar. That's why
parse-only isn't yet beating the mature engine despite the zero-alloc win. The
read path improved (our scalar FindKey + your >64-key hash table), but the
parse path is unchanged.

Pulling main on 2026-07-20 (HEAD 6e54e4b0) confirms it's still dead code — the
only NextGen change since is the Linux compile guard on the asm
({$IFDEF CPUX64}{$IF CPUX64 and MSWINDOWS}). Wiring the SIMD scanner into
the parse loop (or dropping it if superseded) is the missing piece to make NextGen
win on parse-heavy workloads. Not urgent for us (we use the fork directly in the
hot path); flagging so it doesn't get lost.

Thanks!

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions