perf: multiple performance improvements during pre-testing stages#2070
Merged
Conversation
hugo-vrijswijk
commented
Jul 6, 2026
Member
- perf(core): use all cores for parsing, mutating and copying files
- perf(core): render mutated files inside the parallel stage
- perf(core): avoid pretty-printing trees for structural equality
- perf(core): cache reprinted syntax of substitution mutations
- perf(testrunner): skip logging per-mutant test-run messages
- perf(sbt): gate debug logs by configured log level
- perf(logging): cache colorEnabled instead of recomputing it per log line
- perf(core): slim down per-mutant debug log message
concurrency is sized for test-runner processes; the CPU-bound parse/ collect/instrument/copy stages were needlessly capped to the same value
.text was rendered sequentially before being written in parallel, so the whole stage ran on one thread at a time
treeEq rendered both sides to .structure strings on every comparison; walk the tree structurally instead, and check reference equality first in the matcher's transform guard
tree.reprint() was called for the same constant replacement tree on every match instead of once per mutator
colorEnabled re-read sys.env on every single log call
Logging the whole MutantWithId case class stringified the entire mutated tree; log only the useful fields instead
hugo-vrijswijk
force-pushed
the
perf-improvements
branch
from
July 6, 2026 10:29
44ef50a to
16b38a0
Compare
|
Tick the box to add this pull request to the merge queue (same as
|
There was a problem hiding this comment.
Pull request overview
This PR focuses on reducing overhead in Stryker4s’ hot paths by increasing parallelism for CPU-bound stages, avoiding repeated expensive string/tree rendering, and cutting down on per-mutant logging work across runners and build-tool integrations.
Changes:
- Parallelize parsing/mutating/copying/writing work using all available CPU cores, and move mutated-file rendering into the parallel stage.
- Reduce expensive debug/log rendering (skip per-mutant
StartTestRunlogging; slim down per-mutant debug messages; cachecolorEnabled; cache substitution mutation syntax). - Replace
Tree.structure-based equality with a custom structural comparator that ignores positions, with added tests.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| modules/testRunner/src/main/scala/stryker4s/testrunner/server/UnixSocketServer.scala | Avoids logging StartTestRun requests to reduce per-mutant overhead. |
| modules/testRunner/src/main/scala/stryker4s/testrunner/server/TcpSocketServer.scala | Avoids logging StartTestRun requests to reduce per-mutant overhead. |
| modules/testkit/src/main/scala/stryker4s/testkit/TestLogger.scala | Switches colorEnabled to lazy to align with cached evaluation. |
| modules/sbt/src/main/scala/stryker4s/sbt/Stryker4sPlugin.scala | Passes sbt logLevel through to the logger to gate debug output. |
| modules/sbt/src/main/scala/stryker4s/log/SbtLogger.scala | Gates logging by configured minimum sbt level; caches color detection. |
| modules/mill/src/main/scala/stryker4s/log/MillLogger.scala | Caches color detection instead of recomputing per log line. |
| modules/core/src/test/scala/stryker4s/run/MutantRunnerTest.scala | Updates expectations for the new, slimmer per-mutant debug message format. |
| modules/core/src/test/scala/stryker4s/report/mapper/MutantRunResultMapperTest.scala | Updates to use cached substitution mutation syntax. |
| modules/core/src/test/scala/stryker4s/extension/TreeExtensionsTest.scala | Adds tests for the new treeEq structural equality behavior. |
| modules/core/src/main/scala/stryker4s/run/MutantRunner.scala | Uses CPU-parallelism for file copying/writing; moves mutated file rendering into parallel work; slims debug logging. |
| modules/core/src/main/scala/stryker4s/mutation/MutationTypes.scala | Caches tree.reprint() for substitution mutations (treeSyntax). |
| modules/core/src/main/scala/stryker4s/mutants/Mutator.scala | Uses CPU-parallelism for parsing/mutating/instrumenting stages. |
| modules/core/src/main/scala/stryker4s/mutants/findmutants/MutantMatcher.scala | Uses cached substitution syntax when available; avoids expensive equality checks when eq suffices. |
| modules/core/src/main/scala/stryker4s/extension/TreeExtensions.scala | Replaces Tree.structure equality with a custom structural comparator ignoring positions. |
| modules/core/src/main/scala/stryker4s/config/Config.scala | Introduces cpuParallelism as “all cores” parallelism for local CPU-bound work. |
| modules/api/src/main/scala/stryker4s/log/Logger.scala | Caches colorEnabled instead of recomputing it for every log line. |
| maven/src/test/scala/stryker4s/maven/runner/ZincCompilerTest.scala | Adapts tests to use fs2.io.file.Path for jar paths. |
| maven/src/main/scala/stryker4s/maven/Stryker4sMavenRunner.scala | Adapts to resolver APIs returning Path instead of File. |
| maven/src/main/scala/stryker4s/maven/runner/ZincCompiler.scala | Adapts compiler/bridge resolution to Path APIs; converts to File where needed by Zinc. |
| maven/src/main/scala/stryker4s/maven/runner/ArtifactResolver.scala | Switches artifact resolution APIs to return fs2.io.file.Path. |
| maven/src/main/scala/stryker4s/log/MavenMojoLogger.scala | Caches colorEnabled instead of recomputing it for every log line. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.