Skip to main content
← All posts

Parallel Quick Sort: Mechanism, Complexity Analysis & Interactive Visualizer

Md. Harun-Or-RoshidNov 5, 20269 min readArticle
Parallel Quick Sort: Mechanism, Complexity Analysis & Interactive Visualizer
Parallel Sorting · Article 44 of 62

Parallel Quick Sort

A concurrent divide-and-conquer algorithm: partitions the array around pivot elements, spawning child threads to sort sub-partitions in parallel branches of the execution tree.

How it works

Quicksort's divide-and-conquer strategy makes it exceptionally easy to parallelize. Unlike Merge Sort (which does work *after* recursive joins), Quicksort does its work (partitioning) *before* recursion. Parallel Quick Sort runs partition tasks concurrently:

  1. Pivot & Partition: Select a pivot and partition the array segment into two ranges: elements smaller than the pivot, and elements larger than the pivot. This step is performed sequentially on a single thread.
  2. Parallel Task Spawn: Instead of sorting the left and right sub-arrays sequentially, we spawn a new execution thread to sort the right sub-array, while the current thread processes the left sub-array.
  3. Grain-Size Threshold: If sub-array partition sizes fall below a certain threshold (e.g. 1000 elements), the overhead of creating new threads is larger than the benefit. The algorithm therefore switches to standard sequential Quicksort or Insertion Sort for small segments.
  4. Join: Wait for all concurrent sub-tasks to complete, completing the sort without requiring a merge step.

Complexity

Best time
O(n log n)
Average time
O(n log n)
Worst time
O(n²)
Extra space
O(log n)
Stable
No
In-place
Yes
Parallel Quick Sort processes elements in **\(O(\frac{n}{p} \log n + n)\)** time when using \(p\) processors (degrading to \(O(n²)\) if poor pivot choices occur).

Interactive visualization

Pseudocode

procedure parallelQuickSort(A, left, right):
  if right - left < threshold:
    sequentialQuickSort(A, left, right)
  else:
    pivotIdx ← partition(A, left, right)
    
    spawn parallelQuickSort(A, left, pivotIdx - 1)
    parallelQuickSort(A, pivotIdx + 1, right)
    
    sync  # Wait for spawned branch to finish

JavaScript implementation

// Parallel Quicksort using ES6 asynchronous Promise tasks
async function parallelQuickSort(arr, left = 0, right = arr.length - 1) {
  if (left >= right) return;
  
  // Partition size threshold for spawning new worker threads
  const threshold = 500;
  if (right - left < threshold) {
    sequentialQuickSort(arr, left, right);
    return;
  }
  
  const pivotIdx = partition(arr, left, right);
  
  await Promise.all([
    spawnWorkerTask(arr, left, pivotIdx - 1),
    parallelQuickSort(arr, pivotIdx + 1, right)
  ]);
}

Pros and cons

Pros

  • Stunningly fast in-place parallel sort.
  • Requires very little auxiliary space (reuses same memory space).
  • Highly effective load-balancing when pivots partition evenly.

Cons

  • Unstable sorting order.
  • Degrades to \(O(n²)\) if pivots divide partitioning poorly (e.g. sorted arrays).
  • Requires thread synchronization barriers (join steps).

When (not) to use it

  • Multi-core frameworks: Broadly used in high-performance computing, GPU shaders, and system libraries where sorting speed is critical.
  • Safety-critical systems: Avoid when stable sorting is required; choose Parallel Merge Sort instead.
Up next: Parallel Radix Sort — a non-comparison parallel sort that processes digit/byte representation columns concurrently using prefix sums.
Share:
Share on X
Share on LinkedIn
Share on Facebook
Share on Reddit
Share on WhatsApp
Share on Telegram
Copy link

Related reading

Parallel Quick Sort Sorting Algorithm & Guide | Draftsbook · Draftsbook