I am not sure that a PriorityQueue<TElement,TPriority>
is the best collection for your scenario. If you put 20,000 values in the priority queue, you have already paid a significant computational cost for maintaining the heap property while adding the values. This cost is O(n*log n), so it is comparable with sorting a List<T>
. And then you'll have to pay a similar cost for retrieving the values in a sorted order, because the priority queue has to move log(N) elements to maintain the heap, each time you retrieve the min value.
The PriorityQueue<TElement,TPriority>
is a specialized collection, and it's much less flexible than a List<T>
. If you have a sorted list, you can read any element of the list. If you have a priority queue, you can read only the element at the top (the min element). You can't read the next element, without removing (dequeuing) the top element.
If you still think that using a PriorityQueue<TElement,TPriority>
is a good idea, here is what you can do. You can write an extension method that consumes (dequeues) the collection, and returns an IEnumerable
with the consumed elements, like this one:
/// <summary>
/// Gets an enumerable sequence that consumes the elements of the queue
/// in an ordered manner.
/// </summary>
public static IEnumerable<(TElement Element, TPriority Priority)>
GetConsumingEnumerable<TElement, TPriority>(
this PriorityQueue<TElement, TPriority> source)
{
while (source.TryDequeue(out TElement element, out TPriority priority))
{
yield return (element, priority);
}
}
...and then use the Chunk
LINQ operator to batch the consumed elements in chunks of 1000:
IEnumerable<(SomeElementType, SomePriorityType)[]> consumedChunks = queue
.GetConsumingEnumerable().Chunk(1000);