Performance: cheaper Declaration ordering and less evidence-collection allocation Two correctness-preserving performance changes, measured against a corpus of real `.hie` files (the nix-ci3 project: 15 packages, 138 `.hie` files, ~8 MB), built with the matching GHC. Output is byte-identical (same 459 weeds) before and after, and the test suite passes. ## Changes **1. Collect evidence uses directly instead of via `Data.Tree`** `requestEvidence` built a `Tree [Name]` and immediately flattened it away with `concat . Tree.flatten`. The tree was pure allocation overhead; collect the names with a direct recursive concatenation. ~3.8% less total allocation, time neutral. **2. Compare declarations by `Unique` with a structural tie-break** `Ord Declaration` was a *lexical* comparison of the module and occurrence names, paid by every `Set`/`Map Declaration` operation (a hot spot in profiles). Compare by the occurrence name's `FastString` `Unique` (an `Int`, and what its `Eq` already uses) first, falling back to the original structural comparison only to break `Unique` ties -- keeping the instance consistent with the derived `Eq`. Since `Set Declaration` is now ordered by run-dependent `Unique`s, the output sort gets a `displayDeclaration` tie-break so the reported order stays deterministic. Note: comparing the *module* by `Unique` as well was tried and was ~2.3x **slower** -- a `Module`'s `Unique` is not a cached field, so `getUnique` recomputes it on every comparison. Only the occurrence name's `FastString` `Unique` (which is cached) is used. ## Measurements | metric | baseline | after both | delta | |--------|----------|-----------|-------| | serial mutator time | -- | -- | **-15% to -24%** | | total allocation | 14.48 GB | 13.72 GB | **-5.3%** | | weeds reported | 459 | 459 | identical | The mutator-CPU win is large and clean. The user-visible *parallel* wall-clock gain is smaller and noisy on a many-core machine, where parallel GC dominates the variance and masks the mutator improvement. ## Context The previously dominant cost -- `getEvidenceTree` recomputed per (decl, name) -- is already handled by the `analyseEvidenceUses` cache on `master`. These two changes pick up the next pieces. The evidence phase is still the single largest chunk of the run and is largely untouched here.