Skip to content

Array.qsort has quadratic runtime on constant arrays #8087

Description

@TwoFX

Prerequisites

Please put an X between the brackets as you perform the following steps:

Description

def m (n : Nat) := Array.range n
def l (n : Nat) := Array.replicate n 0

#eval ((m 100000).qsort).size -- this is fast
#eval ((l 100000).qsort).size -- this is slow

The problem is that we split the list into "less than pivot" and "greater than or equal to pivot" in a naive way, leading to partition calls of size n, n - 1, n - 2 and so on. Solutions are discussed on Wikipedia; options include using a pivoting procedure like the Hoare rule where an all-equal array returns the center index as the pivoting index, or partitioning the array into three parts: less than pivot, equal to pivot or greater than pivot.

Expected behavior: Quicksort does not take quadratic time for reasonable inputs

Actual behavior: Quicksort takes quadratic time if all inputs are equal

Additional Information

This is apparently the bottleneck in the workspace symbol search LSP request!

Versions

nightly-2025-04-24

Impact

Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-mediumWe may work on this issue if we find the timebugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions