Repository navigation
Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
5 open issues
pthread_setspecificreturns an error code; if it fails, the pointer may remain set and still be… · New Computing an exact Mann–Whitney p-value by enumerating all combinations scales combinatorially… · New This test’s signal is explicitly affected by other parallel tests (process-wide allocator stats),… · Newnonisolated(unsafe)plus cross-thread mutation ofgrowthrelies on informal synchronization and… · New The “up to 30%” claim is a brittle numeric assertion that may drift (and it appears inconsistent… · New
What changed in this PR
Adds a standalone benchmark suite (plus comparison tooling/docs) for Implicits’ store performance/memory behavior, and fixes a thread-store lifetime leak by releasing the TSD value when clearing it.
Changes:
- Introduces
Benchmarks/as a separate SwiftPM package with benchmarks, a macro generator for 10k types, and a Python script to compare builds across interleaved runs. - Documents benchmark results, methodology, and execution instructions in
Benchmarks/README.mdandAGENTS.md. - Fixes a
RawStoreleak by releasing the retained store when clearing thread-specific data; adds a regression test on Darwin.
| File | Description |
|---|---|
| Tests/ImplicitsTests/ImplicitTests.swift | Adds a Darwin-only regression test to detect leaked thread stores via malloc statistics. |
| Sources/Implicits/RawStore.swift | Fixes the thread-store leak by releasing the TSD value when clearing it. |
| Benchmarks/compare.py | Adds a script to compare benchmark builds across multiple interleaved rounds using bootstrap + Mann–Whitney. |
| Benchmarks/README.md | Documents benchmark scenarios, results, analysis, and storage alternatives. |
| Benchmarks/Package.swift | Adds a standalone SwiftPM package for benchmarks and the macro target. |
| Benchmarks/Package.resolved | Pins benchmark dependencies for the standalone package. |
| Benchmarks/Macros/ImplicitsBenchmarksMacros/NewTypesMacro.swift | Adds a macro to generate 10,000 specialized types and touch closures. |
| Benchmarks/ImplicitsBenchmarks/ImplicitsBenchmarks.swift | Adds benchmark definitions, runner setup, and helper harnesses. |
| AGENTS.md | Documents how to run benchmarks and compare results. |
Review effort: Lite
Comment on lines
201
to
207
| private static func clearTSD() { | ||
| guard let ptr = pthread_getspecific(key) else { | ||
| return | ||
| } | ||
| pthread_setspecific(key, nil) | ||
| Unmanaged<RawStore>.fromOpaque(ptr).release() | ||
| } |
Comment on lines
+43
to
+52
| def mann_whitney_p(a, b): | ||
| """Exact two-sided p-value: the share of all splits of the pooled runs whose | ||
| rank-sum statistic is at least as far from its mean as the observed one.""" | ||
| pooled = sorted(a + b) | ||
| rank = {v: statistics.mean(i + 1 for i, w in enumerate(pooled) if w == v) for v in pooled} | ||
| ranks = [rank[v] for v in a + b] | ||
| mean = len(a) * (len(pooled) + 1) / 2 | ||
| observed = abs(sum(ranks[: len(a)]) - mean) | ||
| splits = [abs(sum(c) - mean) >= observed - 1e-9 for c in itertools.combinations(ranks, len(a))] | ||
| return sum(splits) / len(splits) |
Comment on lines
+267
to
+268
| // Byte counts are process-wide and tests run in parallel, so the smallest growth | ||
| // of several attempts is the one least disturbed by other tests. |
Comment on lines
+269
to
+280
| nonisolated(unsafe) var growth = Int.max | ||
| let finished = DispatchSemaphore(value: 0) | ||
| let thread = Thread { | ||
| for _ in 0..<5 { | ||
| let before = bytesInUse() | ||
| for _ in 0..<10000 { | ||
| rootScope() | ||
| } | ||
| growth = min(growth, bytesInUse() - before) | ||
| } | ||
| finished.signal() | ||
| } |
Comment on lines
+8
to
+14
| precondition( | ||
| ProcessInfo.processInfo.environment["SWIFT_DETERMINISTIC_HASHING"] == "1", | ||
| """ | ||
| Run with SWIFT_DETERMINISTIC_HASHING=1: the store is a dictionary, \ | ||
| and a per-process hash seed changes instruction counts between runs by up to 30%. | ||
| """ | ||
| ) |
Copilot stopped reviewing on behalf of
zienag due to an error
October 21, 2026 14:12
zienag
force-pushed
the
store-benchmarks
branch
from
October 26, 2026 16:02
7958826 to
7be6c5f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



There are no measurements of what the implicit store costs, so changes to it, such as replacing
EntryConcrete<T>, get argued without numbers. This adds a benchmark suite for the store, a README that explains where its instructions and memory go, and a script for comparing builds.Changes
Benchmarks/is a separate package on ordo-one/benchmark, so the library gains no dependency. It measures retrieving a value, declaring one in a nested scope, and the one-time cost of a type the process has never stored, over 10,000 types that a macro generates.Benchmarks/README.mdhas the results and explains them:EntryConcrete<T>class metadata;Benchmarks/compare.pycompares builds over several interleaved process runs. One run against one run can't call a regression: the store's dictionary is keyed by metadata addresses, so its layout changes with the binary and moves instruction counts by up to 20%.AGENTS.mdsays how to run the benchmarks.Test plan
swift package --package-path Benchmarks benchmarkruns. CI doesn't build it.