--- Final Solver (used for performance test) ---
import numpy as np
from numba import njit


@njit(cache=False)
def _project(y):
    n = y.shape[0]
    if n == 0:
        return y.copy()

    # Work on a mutable copy for filtering.
    v = y.copy()
    m = n
    theta = 0.0
    work = 0
    limit = 5 * n

    while True:
        s = 0.0
        for i in range(m):
            s += v[i]
        theta = (s - 1.0) / m

        count = 0
        for i in range(m):
            val = v[i]
            if val > theta:
                v[count] = val
                count += 1

        work += m
        if count == m:
            break

        m = count
        if m == 0:
            theta = 0.0
            break

        # Fallback to exact sorted scan if too many filtering passes occur.
        if work > limit:
            u = np.sort(v[:m])
            c = 0.0
            theta = 0.0
            for k in range(m):
                idx = m - 1 - k
                val = u[idx]
                c += val
                kk = k + 1.0
                if val * kk > c - 1.0:
                    theta = (c - 1.0) / kk
                else:
                    break
            break

    x = np.empty(n, dtype=np.float64)
    for i in range(n):
        val = y[i] - theta
        x[i] = val if val > 0.0 else 0.0
    return x


class Solver:
    def __init__(self):
        # Trigger Numba compilation during initialization so it does not count
        # toward solve() runtime.
        _project(np.ones(2, dtype=np.float64))

    def solve(self, problem, **kwargs):
        y = np.asarray(problem.get("y"), dtype=np.float64).ravel()
        x = _project(y)
        return {"solution": x}
--- End Solver ---
Running performance test...
============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.0.2, pluggy-1.6.0
rootdir: /tests
plugins: anyio-4.13.0, jaxtyping-0.3.9
collected 3 items

../tests/test_outputs.py .
--- Performance Summary ---
Validity: True
Total Baseline Time: 6.5615s
Total Solver Time:   2.6218s
Raw Speedup:         2.5027 x
Final Reward (Score): 2.5027
---------------------------
..

==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED ../tests/test_outputs.py::test_solver_exists
PASSED ../tests/test_outputs.py::test_solver_validity
PASSED ../tests/test_outputs.py::test_solver_speedup
======================== 3 passed in 261.03s (0:04:21) =========================
