diff --git a/README.md b/README.md index b759319..596e3e2 100644 --- a/README.md +++ b/README.md @@ -20,160 +20,256 @@ No runtime container, no reflection, no hidden magic - just fast, explicit initialization.

-> [!NOTE] -> This is a maintained fork of `google/wire`. -> The original project is no longer actively maintained. -> This fork preserves Wire’s API and behavior while focusing on: -> -> - 8-10x+ Faster compile times -> - Improved generator determinism -> - Better documentation and developer ergonomics (wire watch etc.) -> -> Existing Wire codebases should work without modification. - -Wire is a code generation tool that automates connecting components using -[dependency injection][]. Dependencies between components are represented in -Wire as function parameters, encouraging explicit initialization instead of -global variables. Because Wire operates without runtime state or reflection, -code written to be used with Wire is useful even for hand-written -initialization. - -For an overview, see the [introductory blog post](https://blog.golang.org/wire). - -[dependency injection]: https://en.wikipedia.org/wiki/Dependency_injection -[godoc]: https://godoc.org/github.com/goforj/wire +**GoForj Wire is a maintained fork of [Google Wire](https://github.com/google/wire).** +Google Wire is archived. This fork adds caching for faster repeat runs, watch +mode, and support for `go tool wire`. You can use it in any Go project. -## Installing +Wire connects your components by generating the Go code that calls their +constructors. You write normal functions and declare which ones Wire can use. +Wire works out the call order and passes each dependency where it's needed. +The result is code you can read, debug, or write by hand. -```sh -go install github.com/goforj/wire/cmd/wire@latest -``` +Already using Google Wire? This fork generated code **84-109x faster on unchanged +runs** in our larger test apps with warm caches. See +[what the fork adds](#why-goforj-wire) and the [measured tradeoffs](#generation-performance). -Ensure `$GOPATH/bin` is in your `$PATH`. +## Why would I use Wire? -### Project-owned tools and workspaces +**Keep writing constructors. Stop maintaining the code that connects them.** -To manage Wire as a project tool dependency, add it to the module and opt into -the tool-based generation command: +An orders API and a background worker might share a service, which needs a +repository, an inventory client, and a mailer. Wiring that by hand is straightforward: -```sh -go get -tool github.com/goforj/wire/cmd/wire -go tool wire gen -generate_command="go tool wire" ./... +```go +// InitializeApp connects the API and worker to the same order service. +func InitializeApp(cfg Config, db *sql.DB, logger *slog.Logger) *App { + repo := NewOrderRepository(db) + inventory := NewInventoryClient(cfg) + mailer := NewMailer(cfg) + orders := NewOrderService(repo, inventory, mailer) + handler := NewOrderHandler(orders, logger) + worker := NewOrderWorker(orders, logger) + return NewApp(handler, worker) +} ``` -Wire then emits a directive that keeps this choice on subsequent runs: +There is nothing wrong with this code. The work comes later: a constructor +changes, a dependency needs its own dependencies, or another command needs a +different combination of the same services. You update each setup function and +keep the call order, arguments, and shared instances straight. + +With Wire, you list the constructors once and declare what you want to build: ```go -//go:generate go tool wire gen -generate_command "go tool wire" +//go:build wireinject + +package orders + +import ( + "database/sql" + "log/slog" + + "github.com/goforj/wire" +) + +// AppSet lists the constructors available to the application. +var AppSet = wire.NewSet( + NewOrderRepository, + NewInventoryClient, + NewMailer, + NewOrderService, + NewOrderHandler, + NewOrderWorker, + NewApp, +) + +// InitializeApp connects the API and worker to the same order service. +func InitializeApp(cfg Config, db *sql.DB, logger *slog.Logger) *App { + wire.Build(AppSet) + return nil +} ``` -This works with `go generate` in a Go workspace without the default command's -`-mod=mod` flag. The project must declare the Wire tool dependency. The tool -directive requires Go 1.24 or newer; the selected Wire version's own Go minimum -also applies. +Run `wire gen`. Wire writes `wire_gen.go` with the same constructor calls as +the manual version above. The build tag keeps the stub out of normal builds. +`Config`, `App`, and the constructors are your application's ordinary Go code; +Wire doesn't require a container or special constructor signatures. -`-generate_command` is available on `gen`, `diff`, and `watch`. Its value is the -command prefix that invokes Wire; Wire appends `gen`, the override itself, and -any build tags. Custom wrappers must forward those arguments. Commands follow -Go generate's argument rules, including Go-style double-quoted arguments and -environment-variable expansion. They are not interpreted by a shell. +### When a dependency changes -Omitting the flag preserves the existing `go run -mod=mod` directive and generated -output. To restore that default, run `wire gen` without the override. +Suppose orders now need an audit log. You add a constructor and change the +service's signature: -## Compatibility with google/wire +```go +// NewAuditLog creates an audit log backed by the application's database. +func NewAuditLog(db *sql.DB) *AuditLog { + return &AuditLog{db: db} +} -Wire remains compatible with codebases that import `github.com/google/wire`. -The generator emits a `//go:generate` directive pointing at this fork so -`go generate` consistently uses the maintained toolchain. +// NewOrderService supplies the dependencies needed to process orders. +func NewOrderService( + repo *OrderRepository, + inventory *InventoryClient, + mailer *Mailer, + audit *AuditLog, +) *OrderService { + return &OrderService{repo: repo, inventory: inventory, mailer: mailer, audit: audit} +} +``` -To keep existing imports unchanged: +Add `NewAuditLog` to `AppSet` and rerun Wire. You don't edit the injector's +signature or hand-update its constructor calls. The generated code now includes: -```sh -go mod edit -replace=github.com/google/wire=github.com/goforj/wire@latest +```go +orderRepository := NewOrderRepository(db) +inventoryClient := NewInventoryClient(cfg) +mailer := NewMailer(cfg) +auditLog := NewAuditLog(db) +orderService := NewOrderService(orderRepository, inventoryClient, mailer, auditLog) ``` -## How Wire Works (in 60 seconds) +The handler and worker still receive the same `orderService`. If you forget to +register `NewAuditLog`, generation fails with a missing-provider error and shows +the dependency chain that needs it. You find out before starting the app. -Wire is a **compile-time dependency injection** tool. Instead of building a runtime -container, Wire generates ordinary Go code that explicitly initializes your -application. +**You still own the design.** You choose constructors, interfaces, and which +values enter the injector. Wire follows those choices; it doesn't discover +services at runtime. Tests can call `NewOrderService` directly with test +dependencies, without running Wire. -There are only two concepts to learn: +If your app has a few constructors and one setup function, hand wiring is +probably enough. Wire earns its place when keeping those calls up to date across +a growing application becomes repetitive. Start with the +[working tutorial](_tutorial/README.md) to try it. -### Providers +## Why GoForj Wire? -A provider is a normal Go function that produces a value (and optionally an error). +**Fast reruns, even with hundreds of dependencies.** In our test apps, unchanged +generation was **84-109x faster than Google Wire** with warm caches. After a +function body edit, it was **18-19x faster**. See the [benchmarks](#generation-performance) +for project sizes, timings, and first-run costs. -```go -func NewDB(cfg Config) (*sql.DB, error) { - // ... -} -```` +Your providers, `wire.Build` calls, provider sets, interface bindings, and +cleanup functions work the same way as in Google Wire. Here's what this fork adds: -Dependencies are expressed as function parameters - no globals, no hidden state. +| Feature | How it helps | +| --- | --- | +| **Faster repeat runs** | Wire caches package information and generated code so it can skip work on later runs. See the [benchmark results](#generation-performance). | +| **Watch mode** | Run `wire watch ./...` to regenerate when Go files change. It uses filesystem notifications, with polling as a fallback. | +| **Pin Wire in your project** | Use `-generate_command="go tool wire"` so `go generate` uses the Wire version in your `go.mod`. This also works in Go workspaces, where the default command's `-mod=mod` flag causes problems. | +| **Workspace fixes** | Change a constructor in another module, rerun Wire, and its generated calls update too. This works with `go.work` and local `replace` directives, even if you keep Wire in a separate tools module. Fixed in [v1.3.0](https://github.com/goforj/wire/releases/tag/v1.3.0). | +| **Cache and profiling tools** | Use `wire cache` to find the cache directory or `wire cache clear` to clear it. For slow runs, `-timings`, `-cpuprofile`, `-memprofile`, and `-trace` help you find where the time goes. | -### Injectors +The generated code still calls your constructors directly, with no runtime +container or reflection. -An injector is a stub function whose body calls `wire.Build(...)`. -Wire replaces this stub with generated code that calls providers in dependency -order. +### Generation performance -```go -func InitializeApp(cfg Config) (*App, error) { - wire.Build(AppSet) - return nil, nil -} +We compared GoForj Wire v1.3.0 with Google Wire at +[`9c25c90`](https://github.com/google/wire/commit/9c25c9016f6825302537c4efdd5e897976f9c826). +For a test app with **117 local packages and 342 external packages**, these were +the median times across five runs: + +| Change | Google Wire | GoForj Wire | Speedup | +| --- | ---: | ---: | ---: | +| Unchanged | 1,582.0 ms | 18.9 ms | 83.7x | +| Function body edit | 1,580.0 ms | 87.3 ms | 18.1x | +| Constructor argument added | 1,604.8 ms | 262.6 ms | 6.1x | +| Import added | 1,567.2 ms | 267.8 ms | 5.9x | + +The app with 42 local and 342 external packages reached **109x** on unchanged +runs. The project with 1,016 local packages and few external dependencies saw +**9x**. The kind of dependencies matters as well as the package count. + +These measurements use Go 1.25.0 on an Apple M4 Max, with Go's dependency build +data already cached. Each edit starts from a warmed Wire cache. They time +**code generation**, not `go build` or your running application. + +First runs can be slower while Wire builds its caches. The workspace fix also +adds some checking: in the large local workspace, a cached rerun went from +59.9 to 62.9 ms. With opt-in content hashing, it went from 62.1 to 72.6 ms because +Wire now reads sibling files that older releases skipped. + +We also compared v1.2.0 and v1.3.0 across Go 1.25, 1.26, and 1.27, checked cold +caches, and compiled the generated code after edits. See the +[full results and raw measurements](docs/performance.md) for the release +comparison, cache settings, and tradeoffs. + +To run the repository's application benchmark: + +```sh +bash scripts/import-benchmarks.sh scenarios ``` -The generated output is plain Go - readable, debuggable, and fast. +That runner prints three-run medians and includes a cold Go cache case. The +five-run comparison above warms Go's dependency build data first; the full +report explains both setups. For the smaller import-only test, run +`bash scripts/import-benchmarks.sh table`. -## Minimal Example +## Installing -```go -// providers.go -type Message string +**Wire v1.3.0 requires Go 1.25 or later.** Check your local and CI Go versions +before upgrading. -func ProvideMessage() Message { - return "hello wire" -} +```sh +go install github.com/goforj/wire/cmd/wire@latest +``` -type Greeter struct { - Msg Message -} +Ensure `$GOPATH/bin` is in your `$PATH`. -func NewGreeter(msg Message) *Greeter { - return &Greeter{Msg: msg} -} +### Pinning Wire in your project -var GreeterSet = wire.NewSet( - ProvideMessage, - NewGreeter, -) +To pin Wire's version in your `go.mod`, add it as a Go tool: + +```sh +go get -tool github.com/goforj/wire/cmd/wire@v1.3.0 +go tool wire gen -generate_command="go tool wire" ./... ``` -```go -// wire.go -//go:build wireinject +Wire adds this command to the generated file: -func InitializeGreeter() *Greeter { - wire.Build(GreeterSet) - return nil -} +```go +//go:generate go tool wire gen -generate_command "go tool wire" ``` -Generate the injector: +Now `go generate` uses `go tool wire` too. This works inside a `go.work` workspace, +where the default `go run -mod=mod` command would fail. Keep the tool dependency +in your `go.mod`. Wire v1.3.0 requires Go 1.25 or later. + +You can use `-generate_command` with `gen`, `diff`, and `watch`. Wire adds `gen`, +the `-generate_command` flag, and any build tags to the command you supply. If +you use a wrapper script, make sure it forwards those arguments. Quoting and +environment variables follow `go generate` rules; shell operators aren't supported. + +Without the flag, Wire generates its usual `go run -mod=mod` directive. Run +`wire gen` without the flag to switch back to that default. + +## Moving from Google Wire + +Keep your existing provider sets and injector stubs. The generator accepts both +`github.com/google/wire` and `github.com/goforj/wire` imports. If your code still +imports Google Wire, keep that dependency in your `go.mod`. You don't need a +`replace` directive to use this generator. + +Install the fork, then run it in your application's module: ```sh -wire +go install github.com/goforj/wire/cmd/wire@v1.3.0 +wire gen ./... ``` -Wire produces `wire_gen.go` containing explicit initialization code with no -runtime dependency on Wire. +Review and commit the regenerated files. Their `//go:generate` command now points +to `github.com/goforj/wire/cmd/wire`, so you'll see a diff even if your providers +haven't changed. To pin the generator version or use it in a `go.work` workspace, +follow [Pinning Wire in your project](#pinning-wire-in-your-project). + +New projects can import `github.com/goforj/wire` directly. Its module and generator +require Go 1.25. The generated initialization code has no runtime dependency on +Wire. ## Running generation manually -Use `make generate` to run `wire gen` across the repository. The CLI remains useful for targeted generation: +Use `make generate` to run `wire gen` across this repository. In your own project, run: ```sh wire @@ -193,7 +289,7 @@ wire watch wire watch ./... ``` -Detects the package root automatically and uses native filesystem notifications when available (with a polling fallback). +Wire finds the package root automatically. It uses filesystem notifications when available and falls back to polling. ## Design Guidance @@ -230,9 +326,9 @@ initialization is often simpler and clearer. ## Project Status -This fork tracks the original Wire feature set while prioritizing performance, -determinism, and documentation. Compatibility with existing Wire codebases is a -core goal. +We maintain this fork so existing Wire projects can keep using it with current +Go tooling. See the [release notes](https://github.com/goforj/wire/releases) for +changes and required Go versions. ## Community diff --git a/docs/benchmarks/cold-go-cache.csv b/docs/benchmarks/cold-go-cache.csv new file mode 100644 index 0000000..1ef82fe --- /dev/null +++ b/docs/benchmarks/cold-go-cache.csv @@ -0,0 +1,13 @@ +profile,version,trial,ms +local-high,v1.2.0,0,7487.182 +local-high,v1.3.0,0,7627.225 +local-high,v1.3.0,1,6945.317 +local-high,v1.2.0,1,7283.108 +local-high,v1.2.0,2,7256.294 +local-high,v1.3.0,2,7435.483 +external-high,v1.2.0,0,10548.371 +external-high,v1.3.0,0,10133.144 +external-high,v1.3.0,1,10281.93 +external-high,v1.2.0,1,10156.272 +external-high,v1.2.0,2,10136.897 +external-high,v1.3.0,2,10218.191 diff --git a/docs/benchmarks/newer-go-comparison.csv b/docs/benchmarks/newer-go-comparison.csv new file mode 100644 index 0000000..069ba49 --- /dev/null +++ b/docs/benchmarks/newer-go-comparison.csv @@ -0,0 +1,241 @@ +toolchain,profile,cache_mode,trial,version,scenario,ms +1.26.3,local-high,mtime,0,v1.2.0,unchanged,60.922 +1.26.3,local-high,mtime,0,v1.2.0,body,138.757 +1.26.3,local-high,mtime,0,v1.2.0,shape,502.716 +1.26.3,local-high,mtime,0,v1.3.0,unchanged,66.359 +1.26.3,local-high,mtime,0,v1.3.0,body,140.299 +1.26.3,local-high,mtime,0,v1.3.0,shape,434.193 +1.26.3,local-high,mtime,1,v1.3.0,unchanged,65.636 +1.26.3,local-high,mtime,1,v1.3.0,body,141.51 +1.26.3,local-high,mtime,1,v1.3.0,shape,431.35 +1.26.3,local-high,mtime,1,v1.2.0,unchanged,63.621 +1.26.3,local-high,mtime,1,v1.2.0,body,140.052 +1.26.3,local-high,mtime,1,v1.2.0,shape,420.623 +1.26.3,local-high,mtime,2,v1.2.0,unchanged,64.859 +1.26.3,local-high,mtime,2,v1.2.0,body,148.76 +1.26.3,local-high,mtime,2,v1.2.0,shape,438.903 +1.26.3,local-high,mtime,2,v1.3.0,unchanged,64.95 +1.26.3,local-high,mtime,2,v1.3.0,body,140.083 +1.26.3,local-high,mtime,2,v1.3.0,shape,410.389 +1.26.3,local-high,mtime,3,v1.3.0,unchanged,64.076 +1.26.3,local-high,mtime,3,v1.3.0,body,134.838 +1.26.3,local-high,mtime,3,v1.3.0,shape,417.922 +1.26.3,local-high,mtime,3,v1.2.0,unchanged,62.555 +1.26.3,local-high,mtime,3,v1.2.0,body,139.969 +1.26.3,local-high,mtime,3,v1.2.0,shape,423.112 +1.26.3,local-high,mtime,4,v1.2.0,unchanged,61.408 +1.26.3,local-high,mtime,4,v1.2.0,body,138.633 +1.26.3,local-high,mtime,4,v1.2.0,shape,411.109 +1.26.3,local-high,mtime,4,v1.3.0,unchanged,62.385 +1.26.3,local-high,mtime,4,v1.3.0,body,136.757 +1.26.3,local-high,mtime,4,v1.3.0,shape,419.258 +1.26.3,local-high,content,0,v1.2.0,unchanged,81.917 +1.26.3,local-high,content,0,v1.2.0,body,170.805 +1.26.3,local-high,content,0,v1.2.0,shape,464.183 +1.26.3,local-high,content,0,v1.3.0,unchanged,74.36 +1.26.3,local-high,content,0,v1.3.0,body,173.664 +1.26.3,local-high,content,0,v1.3.0,shape,451.953 +1.26.3,local-high,content,1,v1.3.0,unchanged,72.997 +1.26.3,local-high,content,1,v1.3.0,body,171.421 +1.26.3,local-high,content,1,v1.3.0,shape,441.859 +1.26.3,local-high,content,1,v1.2.0,unchanged,71.794 +1.26.3,local-high,content,1,v1.2.0,body,169.956 +1.26.3,local-high,content,1,v1.2.0,shape,440.114 +1.26.3,local-high,content,2,v1.2.0,unchanged,73.018 +1.26.3,local-high,content,2,v1.2.0,body,175.972 +1.26.3,local-high,content,2,v1.2.0,shape,438.055 +1.26.3,local-high,content,2,v1.3.0,unchanged,74.406 +1.26.3,local-high,content,2,v1.3.0,body,174.34 +1.26.3,local-high,content,2,v1.3.0,shape,468.181 +1.26.3,local-high,content,3,v1.3.0,unchanged,75.566 +1.26.3,local-high,content,3,v1.3.0,body,175.521 +1.26.3,local-high,content,3,v1.3.0,shape,448.674 +1.26.3,local-high,content,3,v1.2.0,unchanged,73.274 +1.26.3,local-high,content,3,v1.2.0,body,173.669 +1.26.3,local-high,content,3,v1.2.0,shape,443.099 +1.26.3,local-high,content,4,v1.2.0,unchanged,73.838 +1.26.3,local-high,content,4,v1.2.0,body,173.385 +1.26.3,local-high,content,4,v1.2.0,shape,452.678 +1.26.3,local-high,content,4,v1.3.0,unchanged,74.447 +1.26.3,local-high,content,4,v1.3.0,body,170.553 +1.26.3,local-high,content,4,v1.3.0,shape,436.453 +1.26.3,external-high,mtime,0,v1.2.0,unchanged,19.298 +1.26.3,external-high,mtime,0,v1.2.0,body,93.016 +1.26.3,external-high,mtime,0,v1.2.0,shape,331.957 +1.26.3,external-high,mtime,0,v1.3.0,unchanged,19.521 +1.26.3,external-high,mtime,0,v1.3.0,body,87.103 +1.26.3,external-high,mtime,0,v1.3.0,shape,279.499 +1.26.3,external-high,mtime,1,v1.3.0,unchanged,20.012 +1.26.3,external-high,mtime,1,v1.3.0,body,99.305 +1.26.3,external-high,mtime,1,v1.3.0,shape,274.584 +1.26.3,external-high,mtime,1,v1.2.0,unchanged,18.166 +1.26.3,external-high,mtime,1,v1.2.0,body,88.919 +1.26.3,external-high,mtime,1,v1.2.0,shape,262.575 +1.26.3,external-high,mtime,2,v1.2.0,unchanged,19.996 +1.26.3,external-high,mtime,2,v1.2.0,body,88.913 +1.26.3,external-high,mtime,2,v1.2.0,shape,261.798 +1.26.3,external-high,mtime,2,v1.3.0,unchanged,19.147 +1.26.3,external-high,mtime,2,v1.3.0,body,90.002 +1.26.3,external-high,mtime,2,v1.3.0,shape,280.133 +1.26.3,external-high,mtime,3,v1.3.0,unchanged,19.222 +1.26.3,external-high,mtime,3,v1.3.0,body,87.402 +1.26.3,external-high,mtime,3,v1.3.0,shape,270.104 +1.26.3,external-high,mtime,3,v1.2.0,unchanged,19.606 +1.26.3,external-high,mtime,3,v1.2.0,body,91.084 +1.26.3,external-high,mtime,3,v1.2.0,shape,268.714 +1.26.3,external-high,mtime,4,v1.2.0,unchanged,21.846 +1.26.3,external-high,mtime,4,v1.2.0,body,89.721 +1.26.3,external-high,mtime,4,v1.2.0,shape,276.864 +1.26.3,external-high,mtime,4,v1.3.0,unchanged,18.436 +1.26.3,external-high,mtime,4,v1.3.0,body,85.619 +1.26.3,external-high,mtime,4,v1.3.0,shape,258.508 +1.26.3,external-high,content,0,v1.2.0,unchanged,20.071 +1.26.3,external-high,content,0,v1.2.0,body,151.383 +1.26.3,external-high,content,0,v1.2.0,shape,325.355 +1.26.3,external-high,content,0,v1.3.0,unchanged,19.567 +1.26.3,external-high,content,0,v1.3.0,body,148.001 +1.26.3,external-high,content,0,v1.3.0,shape,327.68 +1.26.3,external-high,content,1,v1.3.0,unchanged,20.495 +1.26.3,external-high,content,1,v1.3.0,body,149.986 +1.26.3,external-high,content,1,v1.3.0,shape,311.048 +1.26.3,external-high,content,1,v1.2.0,unchanged,20.634 +1.26.3,external-high,content,1,v1.2.0,body,151.034 +1.26.3,external-high,content,1,v1.2.0,shape,327.038 +1.26.3,external-high,content,2,v1.2.0,unchanged,21.4 +1.26.3,external-high,content,2,v1.2.0,body,150.358 +1.26.3,external-high,content,2,v1.2.0,shape,334.869 +1.26.3,external-high,content,2,v1.3.0,unchanged,20.788 +1.26.3,external-high,content,2,v1.3.0,body,153.642 +1.26.3,external-high,content,2,v1.3.0,shape,338.686 +1.26.3,external-high,content,3,v1.3.0,unchanged,19.847 +1.26.3,external-high,content,3,v1.3.0,body,162.934 +1.26.3,external-high,content,3,v1.3.0,shape,330.397 +1.26.3,external-high,content,3,v1.2.0,unchanged,20.374 +1.26.3,external-high,content,3,v1.2.0,body,152.024 +1.26.3,external-high,content,3,v1.2.0,shape,357.434 +1.26.3,external-high,content,4,v1.2.0,unchanged,20.572 +1.26.3,external-high,content,4,v1.2.0,body,155.703 +1.26.3,external-high,content,4,v1.2.0,shape,322.39 +1.26.3,external-high,content,4,v1.3.0,unchanged,20.473 +1.26.3,external-high,content,4,v1.3.0,body,146.879 +1.26.3,external-high,content,4,v1.3.0,shape,310.578 +1.27.2,local-high,mtime,0,v1.2.0,unchanged,61.819 +1.27.2,local-high,mtime,0,v1.2.0,body,150.314 +1.27.2,local-high,mtime,0,v1.2.0,shape,500.785 +1.27.2,local-high,mtime,0,v1.3.0,unchanged,65.607 +1.27.2,local-high,mtime,0,v1.3.0,body,145.606 +1.27.2,local-high,mtime,0,v1.3.0,shape,423.897 +1.27.2,local-high,mtime,1,v1.3.0,unchanged,64.446 +1.27.2,local-high,mtime,1,v1.3.0,body,142.411 +1.27.2,local-high,mtime,1,v1.3.0,shape,423.563 +1.27.2,local-high,mtime,1,v1.2.0,unchanged,65.542 +1.27.2,local-high,mtime,1,v1.2.0,body,150.072 +1.27.2,local-high,mtime,1,v1.2.0,shape,413.172 +1.27.2,local-high,mtime,2,v1.2.0,unchanged,61.364 +1.27.2,local-high,mtime,2,v1.2.0,body,141.067 +1.27.2,local-high,mtime,2,v1.2.0,shape,665.999 +1.27.2,local-high,mtime,2,v1.3.0,unchanged,63.022 +1.27.2,local-high,mtime,2,v1.3.0,body,138.836 +1.27.2,local-high,mtime,2,v1.3.0,shape,421.227 +1.27.2,local-high,mtime,3,v1.3.0,unchanged,61.517 +1.27.2,local-high,mtime,3,v1.3.0,body,136.614 +1.27.2,local-high,mtime,3,v1.3.0,shape,399.679 +1.27.2,local-high,mtime,3,v1.2.0,unchanged,60.883 +1.27.2,local-high,mtime,3,v1.2.0,body,138.404 +1.27.2,local-high,mtime,3,v1.2.0,shape,389.488 +1.27.2,local-high,mtime,4,v1.2.0,unchanged,60.928 +1.27.2,local-high,mtime,4,v1.2.0,body,134.339 +1.27.2,local-high,mtime,4,v1.2.0,shape,394.651 +1.27.2,local-high,mtime,4,v1.3.0,unchanged,60.038 +1.27.2,local-high,mtime,4,v1.3.0,body,139.344 +1.27.2,local-high,mtime,4,v1.3.0,shape,387.564 +1.27.2,local-high,content,0,v1.2.0,unchanged,69.421 +1.27.2,local-high,content,0,v1.2.0,body,181.924 +1.27.2,local-high,content,0,v1.2.0,shape,423.663 +1.27.2,local-high,content,0,v1.3.0,unchanged,70.152 +1.27.2,local-high,content,0,v1.3.0,body,173.224 +1.27.2,local-high,content,0,v1.3.0,shape,422.784 +1.27.2,local-high,content,1,v1.3.0,unchanged,69.649 +1.27.2,local-high,content,1,v1.3.0,body,169.763 +1.27.2,local-high,content,1,v1.3.0,shape,438.999 +1.27.2,local-high,content,1,v1.2.0,unchanged,71.442 +1.27.2,local-high,content,1,v1.2.0,body,186.526 +1.27.2,local-high,content,1,v1.2.0,shape,415.296 +1.27.2,local-high,content,2,v1.2.0,unchanged,69.564 +1.27.2,local-high,content,2,v1.2.0,body,165.983 +1.27.2,local-high,content,2,v1.2.0,shape,453.892 +1.27.2,local-high,content,2,v1.3.0,unchanged,80.58 +1.27.2,local-high,content,2,v1.3.0,body,182.564 +1.27.2,local-high,content,2,v1.3.0,shape,443.961 +1.27.2,local-high,content,3,v1.3.0,unchanged,75.641 +1.27.2,local-high,content,3,v1.3.0,body,178.881 +1.27.2,local-high,content,3,v1.3.0,shape,439.73 +1.27.2,local-high,content,3,v1.2.0,unchanged,94.36 +1.27.2,local-high,content,3,v1.2.0,body,187.584 +1.27.2,local-high,content,3,v1.2.0,shape,470.815 +1.27.2,local-high,content,4,v1.2.0,unchanged,77.623 +1.27.2,local-high,content,4,v1.2.0,body,187.504 +1.27.2,local-high,content,4,v1.2.0,shape,449.649 +1.27.2,local-high,content,4,v1.3.0,unchanged,71.481 +1.27.2,local-high,content,4,v1.3.0,body,325.203 +1.27.2,local-high,content,4,v1.3.0,shape,449.397 +1.27.2,external-high,mtime,0,v1.2.0,unchanged,19.406 +1.27.2,external-high,mtime,0,v1.2.0,body,95.207 +1.27.2,external-high,mtime,0,v1.2.0,shape,324.342 +1.27.2,external-high,mtime,0,v1.3.0,unchanged,19.609 +1.27.2,external-high,mtime,0,v1.3.0,body,90.416 +1.27.2,external-high,mtime,0,v1.3.0,shape,305.12 +1.27.2,external-high,mtime,1,v1.3.0,unchanged,21.403 +1.27.2,external-high,mtime,1,v1.3.0,body,92.52 +1.27.2,external-high,mtime,1,v1.3.0,shape,289.854 +1.27.2,external-high,mtime,1,v1.2.0,unchanged,33.835 +1.27.2,external-high,mtime,1,v1.2.0,body,97.768 +1.27.2,external-high,mtime,1,v1.2.0,shape,409.431 +1.27.2,external-high,mtime,2,v1.2.0,unchanged,21.638 +1.27.2,external-high,mtime,2,v1.2.0,body,92.461 +1.27.2,external-high,mtime,2,v1.2.0,shape,291.045 +1.27.2,external-high,mtime,2,v1.3.0,unchanged,19.892 +1.27.2,external-high,mtime,2,v1.3.0,body,109.513 +1.27.2,external-high,mtime,2,v1.3.0,shape,467.358 +1.27.2,external-high,mtime,3,v1.3.0,unchanged,23.095 +1.27.2,external-high,mtime,3,v1.3.0,body,93.044 +1.27.2,external-high,mtime,3,v1.3.0,shape,294.048 +1.27.2,external-high,mtime,3,v1.2.0,unchanged,19.615 +1.27.2,external-high,mtime,3,v1.2.0,body,95.279 +1.27.2,external-high,mtime,3,v1.2.0,shape,294.424 +1.27.2,external-high,mtime,4,v1.2.0,unchanged,20.392 +1.27.2,external-high,mtime,4,v1.2.0,body,94.558 +1.27.2,external-high,mtime,4,v1.2.0,shape,308.421 +1.27.2,external-high,mtime,4,v1.3.0,unchanged,23.552 +1.27.2,external-high,mtime,4,v1.3.0,body,96.173 +1.27.2,external-high,mtime,4,v1.3.0,shape,470.395 +1.27.2,external-high,content,0,v1.2.0,unchanged,22.805 +1.27.2,external-high,content,0,v1.2.0,body,150.887 +1.27.2,external-high,content,0,v1.2.0,shape,352.197 +1.27.2,external-high,content,0,v1.3.0,unchanged,20.798 +1.27.2,external-high,content,0,v1.3.0,body,152.549 +1.27.2,external-high,content,0,v1.3.0,shape,378.251 +1.27.2,external-high,content,1,v1.3.0,unchanged,20.795 +1.27.2,external-high,content,1,v1.3.0,body,153.777 +1.27.2,external-high,content,1,v1.3.0,shape,325.195 +1.27.2,external-high,content,1,v1.2.0,unchanged,22.666 +1.27.2,external-high,content,1,v1.2.0,body,180.567 +1.27.2,external-high,content,1,v1.2.0,shape,565.808 +1.27.2,external-high,content,2,v1.2.0,unchanged,23.148 +1.27.2,external-high,content,2,v1.2.0,body,163.153 +1.27.2,external-high,content,2,v1.2.0,shape,418.052 +1.27.2,external-high,content,2,v1.3.0,unchanged,20.965 +1.27.2,external-high,content,2,v1.3.0,body,166.478 +1.27.2,external-high,content,2,v1.3.0,shape,411.494 +1.27.2,external-high,content,3,v1.3.0,unchanged,21.096 +1.27.2,external-high,content,3,v1.3.0,body,151.89 +1.27.2,external-high,content,3,v1.3.0,shape,358.877 +1.27.2,external-high,content,3,v1.2.0,unchanged,20.53 +1.27.2,external-high,content,3,v1.2.0,body,150.272 +1.27.2,external-high,content,3,v1.2.0,shape,310.338 +1.27.2,external-high,content,4,v1.2.0,unchanged,21.208 +1.27.2,external-high,content,4,v1.2.0,body,146.976 +1.27.2,external-high,content,4,v1.2.0,shape,315.426 +1.27.2,external-high,content,4,v1.3.0,unchanged,21.329 +1.27.2,external-high,content,4,v1.3.0,body,154.658 +1.27.2,external-high,content,4,v1.3.0,shape,323.282 diff --git a/docs/benchmarks/release-comparison-go1.25.csv b/docs/benchmarks/release-comparison-go1.25.csv new file mode 100644 index 0000000..df6d21a --- /dev/null +++ b/docs/benchmarks/release-comparison-go1.25.csv @@ -0,0 +1,601 @@ +profile,trial,version,cache_mode,scenario,ms +external-high,0,stock,n/a,wire-cold,1756.253 +external-high,0,stock,n/a,unchanged,1667.037 +external-high,0,stock,n/a,body,1544.813 +external-high,0,stock,n/a,shape,1570.83 +external-high,0,stock,n/a,import,1546.163 +external-high,0,stock,n/a,known-import-toggle,1573.319 +external-high,0,v1.2.0,mtime,wire-cold,1648.651 +external-high,0,v1.2.0,mtime,unchanged,19.591 +external-high,0,v1.2.0,mtime,body,94.541 +external-high,0,v1.2.0,mtime,shape,254.685 +external-high,0,v1.2.0,mtime,import,276.717 +external-high,0,v1.2.0,mtime,known-import-toggle,279.463 +external-high,0,v1.3.0,mtime,wire-cold,1697.418 +external-high,0,v1.3.0,mtime,unchanged,18.924 +external-high,0,v1.3.0,mtime,body,86.761 +external-high,0,v1.3.0,mtime,shape,269.778 +external-high,0,v1.3.0,mtime,import,263.526 +external-high,0,v1.3.0,mtime,known-import-toggle,274.988 +external-high,0,v1.2.0,content,wire-cold,1877.132 +external-high,0,v1.2.0,content,unchanged,19.439 +external-high,0,v1.2.0,content,body,150.086 +external-high,0,v1.2.0,content,shape,313.558 +external-high,0,v1.2.0,content,import,315.638 +external-high,0,v1.2.0,content,known-import-toggle,193.201 +external-high,0,v1.3.0,content,wire-cold,1864.373 +external-high,0,v1.3.0,content,unchanged,20.703 +external-high,0,v1.3.0,content,body,146.609 +external-high,0,v1.3.0,content,shape,315.254 +external-high,0,v1.3.0,content,import,320.135 +external-high,0,v1.3.0,content,known-import-toggle,196.964 +external-high,1,v1.2.0,mtime,wire-cold,1544.048 +external-high,1,v1.2.0,mtime,unchanged,18.34 +external-high,1,v1.2.0,mtime,body,86.605 +external-high,1,v1.2.0,mtime,shape,258.317 +external-high,1,v1.2.0,mtime,import,275.493 +external-high,1,v1.2.0,mtime,known-import-toggle,264.224 +external-high,1,v1.3.0,mtime,wire-cold,1547.103 +external-high,1,v1.3.0,mtime,unchanged,18.404 +external-high,1,v1.3.0,mtime,body,87.253 +external-high,1,v1.3.0,mtime,shape,262.586 +external-high,1,v1.3.0,mtime,import,291.899 +external-high,1,v1.3.0,mtime,known-import-toggle,284.47 +external-high,1,v1.2.0,content,wire-cold,1884.351 +external-high,1,v1.2.0,content,unchanged,21.856 +external-high,1,v1.2.0,content,body,145.81 +external-high,1,v1.2.0,content,shape,329.374 +external-high,1,v1.2.0,content,import,317.374 +external-high,1,v1.2.0,content,known-import-toggle,191.355 +external-high,1,v1.3.0,content,wire-cold,1808.51 +external-high,1,v1.3.0,content,unchanged,19.222 +external-high,1,v1.3.0,content,body,138.539 +external-high,1,v1.3.0,content,shape,302.168 +external-high,1,v1.3.0,content,import,318.224 +external-high,1,v1.3.0,content,known-import-toggle,205.051 +external-high,1,stock,n/a,wire-cold,1592.842 +external-high,1,stock,n/a,unchanged,1549.526 +external-high,1,stock,n/a,body,1590.747 +external-high,1,stock,n/a,shape,1604.779 +external-high,1,stock,n/a,import,1592.054 +external-high,1,stock,n/a,known-import-toggle,1615.101 +external-high,2,v1.3.0,mtime,wire-cold,1584.637 +external-high,2,v1.3.0,mtime,unchanged,19.06 +external-high,2,v1.3.0,mtime,body,88.083 +external-high,2,v1.3.0,mtime,shape,262.523 +external-high,2,v1.3.0,mtime,import,274.947 +external-high,2,v1.3.0,mtime,known-import-toggle,272.286 +external-high,2,v1.2.0,content,wire-cold,1903.168 +external-high,2,v1.2.0,content,unchanged,21.166 +external-high,2,v1.2.0,content,body,144.271 +external-high,2,v1.2.0,content,shape,314.617 +external-high,2,v1.2.0,content,import,333.374 +external-high,2,v1.2.0,content,known-import-toggle,200.291 +external-high,2,v1.3.0,content,wire-cold,1844.696 +external-high,2,v1.3.0,content,unchanged,20.084 +external-high,2,v1.3.0,content,body,139.352 +external-high,2,v1.3.0,content,shape,315.977 +external-high,2,v1.3.0,content,import,313.672 +external-high,2,v1.3.0,content,known-import-toggle,201.086 +external-high,2,stock,n/a,wire-cold,1648.426 +external-high,2,stock,n/a,unchanged,1587.368 +external-high,2,stock,n/a,body,1507.565 +external-high,2,stock,n/a,shape,1633.731 +external-high,2,stock,n/a,import,1669.271 +external-high,2,stock,n/a,known-import-toggle,1544.156 +external-high,2,v1.2.0,mtime,wire-cold,1542.504 +external-high,2,v1.2.0,mtime,unchanged,18.474 +external-high,2,v1.2.0,mtime,body,90.426 +external-high,2,v1.2.0,mtime,shape,265.019 +external-high,2,v1.2.0,mtime,import,265.976 +external-high,2,v1.2.0,mtime,known-import-toggle,270.35 +external-high,3,v1.2.0,content,wire-cold,1828.029 +external-high,3,v1.2.0,content,unchanged,19.972 +external-high,3,v1.2.0,content,body,148.321 +external-high,3,v1.2.0,content,shape,312.56 +external-high,3,v1.2.0,content,import,326.19 +external-high,3,v1.2.0,content,known-import-toggle,197.776 +external-high,3,v1.3.0,content,wire-cold,1853.158 +external-high,3,v1.3.0,content,unchanged,19.894 +external-high,3,v1.3.0,content,body,142.148 +external-high,3,v1.3.0,content,shape,312.494 +external-high,3,v1.3.0,content,import,325.165 +external-high,3,v1.3.0,content,known-import-toggle,196.087 +external-high,3,stock,n/a,wire-cold,1592.082 +external-high,3,stock,n/a,unchanged,1573.995 +external-high,3,stock,n/a,body,1596.583 +external-high,3,stock,n/a,shape,1560.602 +external-high,3,stock,n/a,import,1552.445 +external-high,3,stock,n/a,known-import-toggle,1574.893 +external-high,3,v1.2.0,mtime,wire-cold,1552.241 +external-high,3,v1.2.0,mtime,unchanged,17.845 +external-high,3,v1.2.0,mtime,body,84.284 +external-high,3,v1.2.0,mtime,shape,253.884 +external-high,3,v1.2.0,mtime,import,269.849 +external-high,3,v1.2.0,mtime,known-import-toggle,268.627 +external-high,3,v1.3.0,mtime,wire-cold,1561.707 +external-high,3,v1.3.0,mtime,unchanged,18.898 +external-high,3,v1.3.0,mtime,body,87.527 +external-high,3,v1.3.0,mtime,shape,260.127 +external-high,3,v1.3.0,mtime,import,266.279 +external-high,3,v1.3.0,mtime,known-import-toggle,261.452 +external-high,4,v1.3.0,content,wire-cold,1872.055 +external-high,4,v1.3.0,content,unchanged,19.966 +external-high,4,v1.3.0,content,body,146.142 +external-high,4,v1.3.0,content,shape,313.305 +external-high,4,v1.3.0,content,import,328.986 +external-high,4,v1.3.0,content,known-import-toggle,204.747 +external-high,4,stock,n/a,wire-cold,1600.328 +external-high,4,stock,n/a,unchanged,1582.004 +external-high,4,stock,n/a,body,1580.019 +external-high,4,stock,n/a,shape,1614.754 +external-high,4,stock,n/a,import,1567.15 +external-high,4,stock,n/a,known-import-toggle,1569.128 +external-high,4,v1.2.0,mtime,wire-cold,1550.634 +external-high,4,v1.2.0,mtime,unchanged,18.39 +external-high,4,v1.2.0,mtime,body,87.457 +external-high,4,v1.2.0,mtime,shape,259.822 +external-high,4,v1.2.0,mtime,import,266.523 +external-high,4,v1.2.0,mtime,known-import-toggle,278.232 +external-high,4,v1.3.0,mtime,wire-cold,1571.686 +external-high,4,v1.3.0,mtime,unchanged,18.817 +external-high,4,v1.3.0,mtime,body,86.323 +external-high,4,v1.3.0,mtime,shape,263.039 +external-high,4,v1.3.0,mtime,import,267.779 +external-high,4,v1.3.0,mtime,known-import-toggle,292.008 +external-high,4,v1.2.0,content,wire-cold,1891.472 +external-high,4,v1.2.0,content,unchanged,19.953 +external-high,4,v1.2.0,content,body,153.386 +external-high,4,v1.2.0,content,shape,337.696 +external-high,4,v1.2.0,content,import,331.747 +external-high,4,v1.2.0,content,known-import-toggle,204.73 +external-low,0,stock,n/a,wire-cold,1654.503 +external-low,0,stock,n/a,unchanged,1548.981 +external-low,0,stock,n/a,body,1579.931 +external-low,0,stock,n/a,shape,1580.235 +external-low,0,stock,n/a,import,1591.894 +external-low,0,stock,n/a,known-import-toggle,1628.038 +external-low,0,v1.2.0,mtime,wire-cold,1523.653 +external-low,0,v1.2.0,mtime,unchanged,14.415 +external-low,0,v1.2.0,mtime,body,78.533 +external-low,0,v1.2.0,mtime,shape,278.777 +external-low,0,v1.2.0,mtime,import,280.37 +external-low,0,v1.2.0,mtime,known-import-toggle,243.019 +external-low,0,v1.3.0,mtime,wire-cold,1555.405 +external-low,0,v1.3.0,mtime,unchanged,14.406 +external-low,0,v1.3.0,mtime,body,81.401 +external-low,0,v1.3.0,mtime,shape,241.896 +external-low,0,v1.3.0,mtime,import,240.047 +external-low,0,v1.3.0,mtime,known-import-toggle,245.125 +external-low,0,v1.2.0,content,wire-cold,1812.687 +external-low,0,v1.2.0,content,unchanged,14.935 +external-low,0,v1.2.0,content,body,148.35 +external-low,0,v1.2.0,content,shape,302.185 +external-low,0,v1.2.0,content,import,300.963 +external-low,0,v1.2.0,content,known-import-toggle,181.139 +external-low,0,v1.3.0,content,wire-cold,1838.422 +external-low,0,v1.3.0,content,unchanged,15.179 +external-low,0,v1.3.0,content,body,135.283 +external-low,0,v1.3.0,content,shape,294.447 +external-low,0,v1.3.0,content,import,299.797 +external-low,0,v1.3.0,content,known-import-toggle,175.53 +external-low,1,v1.2.0,mtime,wire-cold,1503.387 +external-low,1,v1.2.0,mtime,unchanged,15.357 +external-low,1,v1.2.0,mtime,body,80.965 +external-low,1,v1.2.0,mtime,shape,240.206 +external-low,1,v1.2.0,mtime,import,245.576 +external-low,1,v1.2.0,mtime,known-import-toggle,244.635 +external-low,1,v1.3.0,mtime,wire-cold,1526.387 +external-low,1,v1.3.0,mtime,unchanged,14.434 +external-low,1,v1.3.0,mtime,body,77.099 +external-low,1,v1.3.0,mtime,shape,242.336 +external-low,1,v1.3.0,mtime,import,239.819 +external-low,1,v1.3.0,mtime,known-import-toggle,242.033 +external-low,1,v1.2.0,content,wire-cold,1800.425 +external-low,1,v1.2.0,content,unchanged,14.665 +external-low,1,v1.2.0,content,body,136.322 +external-low,1,v1.2.0,content,shape,299.155 +external-low,1,v1.2.0,content,import,300.453 +external-low,1,v1.2.0,content,known-import-toggle,181.635 +external-low,1,v1.3.0,content,wire-cold,1842.868 +external-low,1,v1.3.0,content,unchanged,15.512 +external-low,1,v1.3.0,content,body,131.059 +external-low,1,v1.3.0,content,shape,307.757 +external-low,1,v1.3.0,content,import,295.267 +external-low,1,v1.3.0,content,known-import-toggle,183.607 +external-low,1,stock,n/a,wire-cold,1626.603 +external-low,1,stock,n/a,unchanged,1552.724 +external-low,1,stock,n/a,body,1563.657 +external-low,1,stock,n/a,shape,1543.878 +external-low,1,stock,n/a,import,1560.306 +external-low,1,stock,n/a,known-import-toggle,1564.635 +external-low,2,v1.3.0,mtime,wire-cold,1540.903 +external-low,2,v1.3.0,mtime,unchanged,14.461 +external-low,2,v1.3.0,mtime,body,76.296 +external-low,2,v1.3.0,mtime,shape,232.861 +external-low,2,v1.3.0,mtime,import,252.799 +external-low,2,v1.3.0,mtime,known-import-toggle,244.212 +external-low,2,v1.2.0,content,wire-cold,1809.172 +external-low,2,v1.2.0,content,unchanged,15.05 +external-low,2,v1.2.0,content,body,135.081 +external-low,2,v1.2.0,content,shape,295.823 +external-low,2,v1.2.0,content,import,301.355 +external-low,2,v1.2.0,content,known-import-toggle,175.176 +external-low,2,v1.3.0,content,wire-cold,1812.931 +external-low,2,v1.3.0,content,unchanged,14.929 +external-low,2,v1.3.0,content,body,129.855 +external-low,2,v1.3.0,content,shape,295.07 +external-low,2,v1.3.0,content,import,309.512 +external-low,2,v1.3.0,content,known-import-toggle,174.705 +external-low,2,stock,n/a,wire-cold,1551.731 +external-low,2,stock,n/a,unchanged,1613.246 +external-low,2,stock,n/a,body,1611.52 +external-low,2,stock,n/a,shape,1562.962 +external-low,2,stock,n/a,import,1565.307 +external-low,2,stock,n/a,known-import-toggle,1550.269 +external-low,2,v1.2.0,mtime,wire-cold,1519.845 +external-low,2,v1.2.0,mtime,unchanged,14.656 +external-low,2,v1.2.0,mtime,body,80.153 +external-low,2,v1.2.0,mtime,shape,240.747 +external-low,2,v1.2.0,mtime,import,247.176 +external-low,2,v1.2.0,mtime,known-import-toggle,244.519 +external-low,3,v1.2.0,content,wire-cold,1836.065 +external-low,3,v1.2.0,content,unchanged,15.186 +external-low,3,v1.2.0,content,body,135.962 +external-low,3,v1.2.0,content,shape,308.462 +external-low,3,v1.2.0,content,import,309.19 +external-low,3,v1.2.0,content,known-import-toggle,185.413 +external-low,3,v1.3.0,content,wire-cold,1816.693 +external-low,3,v1.3.0,content,unchanged,16.332 +external-low,3,v1.3.0,content,body,137.179 +external-low,3,v1.3.0,content,shape,307.266 +external-low,3,v1.3.0,content,import,300.458 +external-low,3,v1.3.0,content,known-import-toggle,178.038 +external-low,3,stock,n/a,wire-cold,1517.418 +external-low,3,stock,n/a,unchanged,1581.03 +external-low,3,stock,n/a,body,1504.796 +external-low,3,stock,n/a,shape,1596.159 +external-low,3,stock,n/a,import,1543.581 +external-low,3,stock,n/a,known-import-toggle,1541.811 +external-low,3,v1.2.0,mtime,wire-cold,1563.708 +external-low,3,v1.2.0,mtime,unchanged,14.186 +external-low,3,v1.2.0,mtime,body,80.288 +external-low,3,v1.2.0,mtime,shape,247.263 +external-low,3,v1.2.0,mtime,import,262.44 +external-low,3,v1.2.0,mtime,known-import-toggle,262.351 +external-low,3,v1.3.0,mtime,wire-cold,1614.139 +external-low,3,v1.3.0,mtime,unchanged,15.516 +external-low,3,v1.3.0,mtime,body,81.644 +external-low,3,v1.3.0,mtime,shape,251.528 +external-low,3,v1.3.0,mtime,import,265.893 +external-low,3,v1.3.0,mtime,known-import-toggle,238.735 +external-low,4,v1.3.0,content,wire-cold,1878.914 +external-low,4,v1.3.0,content,unchanged,15.033 +external-low,4,v1.3.0,content,body,138.39 +external-low,4,v1.3.0,content,shape,299.317 +external-low,4,v1.3.0,content,import,304.404 +external-low,4,v1.3.0,content,known-import-toggle,186.007 +external-low,4,stock,n/a,wire-cold,1667.713 +external-low,4,stock,n/a,unchanged,1614.997 +external-low,4,stock,n/a,body,1644.968 +external-low,4,stock,n/a,shape,1635.55 +external-low,4,stock,n/a,import,1651.563 +external-low,4,stock,n/a,known-import-toggle,1594.743 +external-low,4,v1.2.0,mtime,wire-cold,1558.709 +external-low,4,v1.2.0,mtime,unchanged,14.939 +external-low,4,v1.2.0,mtime,body,79.963 +external-low,4,v1.2.0,mtime,shape,241.33 +external-low,4,v1.2.0,mtime,import,245.279 +external-low,4,v1.2.0,mtime,known-import-toggle,239.777 +external-low,4,v1.3.0,mtime,wire-cold,1540.907 +external-low,4,v1.3.0,mtime,unchanged,15.34 +external-low,4,v1.3.0,mtime,body,82.42 +external-low,4,v1.3.0,mtime,shape,255.136 +external-low,4,v1.3.0,mtime,import,243.092 +external-low,4,v1.3.0,mtime,known-import-toggle,256.243 +external-low,4,v1.2.0,content,wire-cold,1877.172 +external-low,4,v1.2.0,content,unchanged,14.922 +external-low,4,v1.2.0,content,body,142.273 +external-low,4,v1.2.0,content,shape,296.703 +external-low,4,v1.2.0,content,import,312.267 +external-low,4,v1.2.0,content,known-import-toggle,180.755 +local,0,stock,n/a,wire-cold,417.625 +local,0,stock,n/a,unchanged,392.784 +local,0,stock,n/a,body,396.892 +local,0,stock,n/a,shape,409.933 +local,0,stock,n/a,import,398.59 +local,0,stock,n/a,known-import-toggle,401.482 +local,0,v1.2.0,mtime,wire-cold,390.175 +local,0,v1.2.0,mtime,unchanged,8.931 +local,0,v1.2.0,mtime,body,26.882 +local,0,v1.2.0,mtime,shape,139.735 +local,0,v1.2.0,mtime,import,135.543 +local,0,v1.2.0,mtime,known-import-toggle,102.255 +local,0,v1.3.0,mtime,wire-cold,385.252 +local,0,v1.3.0,mtime,unchanged,9.295 +local,0,v1.3.0,mtime,body,26.99 +local,0,v1.3.0,mtime,shape,107.275 +local,0,v1.3.0,mtime,import,99.909 +local,0,v1.3.0,mtime,known-import-toggle,107.514 +local,0,v1.2.0,content,wire-cold,448.746 +local,0,v1.2.0,content,unchanged,9.971 +local,0,v1.2.0,content,body,44.509 +local,0,v1.2.0,content,shape,115.095 +local,0,v1.2.0,content,import,112.993 +local,0,v1.2.0,content,known-import-toggle,83.219 +local,0,v1.3.0,content,wire-cold,472.499 +local,0,v1.3.0,content,unchanged,10.198 +local,0,v1.3.0,content,body,41.8 +local,0,v1.3.0,content,shape,116.054 +local,0,v1.3.0,content,import,115.087 +local,0,v1.3.0,content,known-import-toggle,87.018 +local,1,v1.2.0,mtime,wire-cold,379.707 +local,1,v1.2.0,mtime,unchanged,9.092 +local,1,v1.2.0,mtime,body,27.383 +local,1,v1.2.0,mtime,shape,98.782 +local,1,v1.2.0,mtime,import,97.526 +local,1,v1.2.0,mtime,known-import-toggle,99.49 +local,1,v1.3.0,mtime,wire-cold,382.552 +local,1,v1.3.0,mtime,unchanged,9.502 +local,1,v1.3.0,mtime,body,27.416 +local,1,v1.3.0,mtime,shape,100.977 +local,1,v1.3.0,mtime,import,102.455 +local,1,v1.3.0,mtime,known-import-toggle,101.191 +local,1,v1.2.0,content,wire-cold,454.546 +local,1,v1.2.0,content,unchanged,9.383 +local,1,v1.2.0,content,body,41.177 +local,1,v1.2.0,content,shape,118.019 +local,1,v1.2.0,content,import,118.116 +local,1,v1.2.0,content,known-import-toggle,81.37 +local,1,v1.3.0,content,wire-cold,445.413 +local,1,v1.3.0,content,unchanged,9.518 +local,1,v1.3.0,content,body,41.056 +local,1,v1.3.0,content,shape,112.812 +local,1,v1.3.0,content,import,118.356 +local,1,v1.3.0,content,known-import-toggle,85.346 +local,1,stock,n/a,wire-cold,384.612 +local,1,stock,n/a,unchanged,394.73 +local,1,stock,n/a,body,394.168 +local,1,stock,n/a,shape,382.942 +local,1,stock,n/a,import,398.087 +local,1,stock,n/a,known-import-toggle,403.674 +local,2,v1.3.0,mtime,wire-cold,371.883 +local,2,v1.3.0,mtime,unchanged,8.728 +local,2,v1.3.0,mtime,body,25.184 +local,2,v1.3.0,mtime,shape,95.415 +local,2,v1.3.0,mtime,import,99.839 +local,2,v1.3.0,mtime,known-import-toggle,100.424 +local,2,v1.2.0,content,wire-cold,444.635 +local,2,v1.2.0,content,unchanged,10.094 +local,2,v1.2.0,content,body,43.115 +local,2,v1.2.0,content,shape,109.198 +local,2,v1.2.0,content,import,113.174 +local,2,v1.2.0,content,known-import-toggle,80.58 +local,2,v1.3.0,content,wire-cold,438.461 +local,2,v1.3.0,content,unchanged,9.596 +local,2,v1.3.0,content,body,45.727 +local,2,v1.3.0,content,shape,116.007 +local,2,v1.3.0,content,import,110.524 +local,2,v1.3.0,content,known-import-toggle,79.425 +local,2,stock,n/a,wire-cold,379.869 +local,2,stock,n/a,unchanged,388.178 +local,2,stock,n/a,body,389.568 +local,2,stock,n/a,shape,402.562 +local,2,stock,n/a,import,386.916 +local,2,stock,n/a,known-import-toggle,391.16 +local,2,v1.2.0,mtime,wire-cold,377.146 +local,2,v1.2.0,mtime,unchanged,8.987 +local,2,v1.2.0,mtime,body,28.857 +local,2,v1.2.0,mtime,shape,101.244 +local,2,v1.2.0,mtime,import,103.048 +local,2,v1.2.0,mtime,known-import-toggle,99.319 +local,3,v1.2.0,content,wire-cold,456.969 +local,3,v1.2.0,content,unchanged,9.635 +local,3,v1.2.0,content,body,42.296 +local,3,v1.2.0,content,shape,116.468 +local,3,v1.2.0,content,import,116.061 +local,3,v1.2.0,content,known-import-toggle,84.261 +local,3,v1.3.0,content,wire-cold,452.138 +local,3,v1.3.0,content,unchanged,10.229 +local,3,v1.3.0,content,body,41.875 +local,3,v1.3.0,content,shape,120.0 +local,3,v1.3.0,content,import,123.327 +local,3,v1.3.0,content,known-import-toggle,85.567 +local,3,stock,n/a,wire-cold,401.739 +local,3,stock,n/a,unchanged,404.705 +local,3,stock,n/a,body,391.715 +local,3,stock,n/a,shape,427.425 +local,3,stock,n/a,import,388.725 +local,3,stock,n/a,known-import-toggle,392.563 +local,3,v1.2.0,mtime,wire-cold,373.316 +local,3,v1.2.0,mtime,unchanged,9.133 +local,3,v1.2.0,mtime,body,26.005 +local,3,v1.2.0,mtime,shape,95.372 +local,3,v1.2.0,mtime,import,101.473 +local,3,v1.2.0,mtime,known-import-toggle,101.335 +local,3,v1.3.0,mtime,wire-cold,372.45 +local,3,v1.3.0,mtime,unchanged,9.592 +local,3,v1.3.0,mtime,body,26.779 +local,3,v1.3.0,mtime,shape,99.898 +local,3,v1.3.0,mtime,import,102.732 +local,3,v1.3.0,mtime,known-import-toggle,102.956 +local,4,v1.3.0,content,wire-cold,444.156 +local,4,v1.3.0,content,unchanged,10.115 +local,4,v1.3.0,content,body,42.78 +local,4,v1.3.0,content,shape,117.716 +local,4,v1.3.0,content,import,123.831 +local,4,v1.3.0,content,known-import-toggle,86.556 +local,4,stock,n/a,wire-cold,405.628 +local,4,stock,n/a,unchanged,407.211 +local,4,stock,n/a,body,390.867 +local,4,stock,n/a,shape,400.864 +local,4,stock,n/a,import,404.613 +local,4,stock,n/a,known-import-toggle,395.975 +local,4,v1.2.0,mtime,wire-cold,381.588 +local,4,v1.2.0,mtime,unchanged,9.633 +local,4,v1.2.0,mtime,body,28.134 +local,4,v1.2.0,mtime,shape,99.882 +local,4,v1.2.0,mtime,import,103.453 +local,4,v1.2.0,mtime,known-import-toggle,108.772 +local,4,v1.3.0,mtime,wire-cold,378.073 +local,4,v1.3.0,mtime,unchanged,9.069 +local,4,v1.3.0,mtime,body,26.849 +local,4,v1.3.0,mtime,shape,100.865 +local,4,v1.3.0,mtime,import,99.564 +local,4,v1.3.0,mtime,known-import-toggle,102.045 +local,4,v1.2.0,content,wire-cold,447.237 +local,4,v1.2.0,content,unchanged,9.671 +local,4,v1.2.0,content,body,42.807 +local,4,v1.2.0,content,shape,114.212 +local,4,v1.2.0,content,import,121.573 +local,4,v1.2.0,content,known-import-toggle,85.532 +local-high,0,stock,n/a,wire-cold,580.939 +local-high,0,stock,n/a,unchanged,548.847 +local-high,0,stock,n/a,body,543.294 +local-high,0,stock,n/a,shape,540.599 +local-high,0,stock,n/a,import,521.901 +local-high,0,stock,n/a,known-import-toggle,564.979 +local-high,0,v1.2.0,mtime,wire-cold,742.819 +local-high,0,v1.2.0,mtime,unchanged,64.071 +local-high,0,v1.2.0,mtime,body,135.814 +local-high,0,v1.2.0,mtime,shape,505.924 +local-high,0,v1.2.0,mtime,import,496.992 +local-high,0,v1.2.0,mtime,known-import-toggle,394.981 +local-high,0,v1.3.0,mtime,wire-cold,713.827 +local-high,0,v1.3.0,mtime,unchanged,62.061 +local-high,0,v1.3.0,mtime,body,130.956 +local-high,0,v1.3.0,mtime,shape,407.264 +local-high,0,v1.3.0,mtime,import,423.649 +local-high,0,v1.3.0,mtime,known-import-toggle,422.972 +local-high,0,v1.2.0,content,wire-cold,784.568 +local-high,0,v1.2.0,content,unchanged,69.771 +local-high,0,v1.2.0,content,body,164.319 +local-high,0,v1.2.0,content,shape,430.795 +local-high,0,v1.2.0,content,import,420.035 +local-high,0,v1.2.0,content,known-import-toggle,340.626 +local-high,0,v1.3.0,content,wire-cold,819.271 +local-high,0,v1.3.0,content,unchanged,72.583 +local-high,0,v1.3.0,content,body,180.631 +local-high,0,v1.3.0,content,shape,446.037 +local-high,0,v1.3.0,content,import,464.426 +local-high,0,v1.3.0,content,known-import-toggle,364.215 +local-high,1,v1.2.0,mtime,wire-cold,694.396 +local-high,1,v1.2.0,mtime,unchanged,64.834 +local-high,1,v1.2.0,mtime,body,135.142 +local-high,1,v1.2.0,mtime,shape,397.165 +local-high,1,v1.2.0,mtime,import,408.574 +local-high,1,v1.2.0,mtime,known-import-toggle,406.795 +local-high,1,v1.3.0,mtime,wire-cold,708.714 +local-high,1,v1.3.0,mtime,unchanged,61.696 +local-high,1,v1.3.0,mtime,body,136.542 +local-high,1,v1.3.0,mtime,shape,398.923 +local-high,1,v1.3.0,mtime,import,381.269 +local-high,1,v1.3.0,mtime,known-import-toggle,397.389 +local-high,1,v1.2.0,content,wire-cold,783.387 +local-high,1,v1.2.0,content,unchanged,69.05 +local-high,1,v1.2.0,content,body,163.803 +local-high,1,v1.2.0,content,shape,416.999 +local-high,1,v1.2.0,content,import,413.59 +local-high,1,v1.2.0,content,known-import-toggle,315.775 +local-high,1,v1.3.0,content,wire-cold,791.984 +local-high,1,v1.3.0,content,unchanged,68.431 +local-high,1,v1.3.0,content,body,163.197 +local-high,1,v1.3.0,content,shape,413.953 +local-high,1,v1.3.0,content,import,412.455 +local-high,1,v1.3.0,content,known-import-toggle,329.672 +local-high,1,stock,n/a,wire-cold,557.988 +local-high,1,stock,n/a,unchanged,508.957 +local-high,1,stock,n/a,body,514.331 +local-high,1,stock,n/a,shape,498.235 +local-high,1,stock,n/a,import,494.703 +local-high,1,stock,n/a,known-import-toggle,505.066 +local-high,2,v1.3.0,mtime,wire-cold,689.334 +local-high,2,v1.3.0,mtime,unchanged,59.772 +local-high,2,v1.3.0,mtime,body,130.409 +local-high,2,v1.3.0,mtime,shape,406.216 +local-high,2,v1.3.0,mtime,import,386.494 +local-high,2,v1.3.0,mtime,known-import-toggle,389.639 +local-high,2,v1.2.0,content,wire-cold,793.041 +local-high,2,v1.2.0,content,unchanged,70.778 +local-high,2,v1.2.0,content,body,167.667 +local-high,2,v1.2.0,content,shape,426.183 +local-high,2,v1.2.0,content,import,435.692 +local-high,2,v1.2.0,content,known-import-toggle,329.651 +local-high,2,v1.3.0,content,wire-cold,806.998 +local-high,2,v1.3.0,content,unchanged,70.265 +local-high,2,v1.3.0,content,body,173.619 +local-high,2,v1.3.0,content,shape,435.717 +local-high,2,v1.3.0,content,import,431.382 +local-high,2,v1.3.0,content,known-import-toggle,338.766 +local-high,2,stock,n/a,wire-cold,524.824 +local-high,2,stock,n/a,unchanged,544.097 +local-high,2,stock,n/a,body,519.94 +local-high,2,stock,n/a,shape,519.482 +local-high,2,stock,n/a,import,509.298 +local-high,2,stock,n/a,known-import-toggle,514.435 +local-high,2,v1.2.0,mtime,wire-cold,739.231 +local-high,2,v1.2.0,mtime,unchanged,59.171 +local-high,2,v1.2.0,mtime,body,129.264 +local-high,2,v1.2.0,mtime,shape,395.001 +local-high,2,v1.2.0,mtime,import,387.962 +local-high,2,v1.2.0,mtime,known-import-toggle,437.889 +local-high,3,v1.2.0,content,wire-cold,822.29 +local-high,3,v1.2.0,content,unchanged,72.845 +local-high,3,v1.2.0,content,body,168.971 +local-high,3,v1.2.0,content,shape,449.254 +local-high,3,v1.2.0,content,import,432.132 +local-high,3,v1.2.0,content,known-import-toggle,326.747 +local-high,3,v1.3.0,content,wire-cold,783.995 +local-high,3,v1.3.0,content,unchanged,71.312 +local-high,3,v1.3.0,content,body,166.767 +local-high,3,v1.3.0,content,shape,439.923 +local-high,3,v1.3.0,content,import,439.374 +local-high,3,v1.3.0,content,known-import-toggle,329.145 +local-high,3,stock,n/a,wire-cold,529.562 +local-high,3,stock,n/a,unchanged,550.389 +local-high,3,stock,n/a,body,561.547 +local-high,3,stock,n/a,shape,545.626 +local-high,3,stock,n/a,import,545.143 +local-high,3,stock,n/a,known-import-toggle,537.877 +local-high,3,v1.2.0,mtime,wire-cold,737.118 +local-high,3,v1.2.0,mtime,unchanged,62.55 +local-high,3,v1.2.0,mtime,body,139.293 +local-high,3,v1.2.0,mtime,shape,423.151 +local-high,3,v1.2.0,mtime,import,408.349 +local-high,3,v1.2.0,mtime,known-import-toggle,414.617 +local-high,3,v1.3.0,mtime,wire-cold,733.429 +local-high,3,v1.3.0,mtime,unchanged,60.25 +local-high,3,v1.3.0,mtime,body,132.728 +local-high,3,v1.3.0,mtime,shape,427.165 +local-high,3,v1.3.0,mtime,import,408.263 +local-high,3,v1.3.0,mtime,known-import-toggle,413.457 +local-high,4,v1.3.0,content,wire-cold,802.44 +local-high,4,v1.3.0,content,unchanged,74.206 +local-high,4,v1.3.0,content,body,171.889 +local-high,4,v1.3.0,content,shape,445.276 +local-high,4,v1.3.0,content,import,441.673 +local-high,4,v1.3.0,content,known-import-toggle,345.792 +local-high,4,stock,n/a,wire-cold,564.453 +local-high,4,stock,n/a,unchanged,531.832 +local-high,4,stock,n/a,body,565.831 +local-high,4,stock,n/a,shape,535.008 +local-high,4,stock,n/a,import,556.113 +local-high,4,stock,n/a,known-import-toggle,550.443 +local-high,4,v1.2.0,mtime,wire-cold,729.622 +local-high,4,v1.2.0,mtime,unchanged,63.059 +local-high,4,v1.2.0,mtime,body,138.891 +local-high,4,v1.2.0,mtime,shape,420.149 +local-high,4,v1.2.0,mtime,import,428.866 +local-high,4,v1.2.0,mtime,known-import-toggle,426.158 +local-high,4,v1.3.0,mtime,wire-cold,744.245 +local-high,4,v1.3.0,mtime,unchanged,60.109 +local-high,4,v1.3.0,mtime,body,136.139 +local-high,4,v1.3.0,mtime,shape,417.518 +local-high,4,v1.3.0,mtime,import,417.864 +local-high,4,v1.3.0,mtime,known-import-toggle,420.005 +local-high,4,v1.2.0,content,wire-cold,816.072 +local-high,4,v1.2.0,content,unchanged,73.851 +local-high,4,v1.2.0,content,body,172.11 +local-high,4,v1.2.0,content,shape,449.843 +local-high,4,v1.2.0,content,import,458.085 +local-high,4,v1.2.0,content,known-import-toggle,350.654 diff --git a/docs/benchmarks/workspace-comparison.csv b/docs/benchmarks/workspace-comparison.csv new file mode 100644 index 0000000..09824fc --- /dev/null +++ b/docs/benchmarks/workspace-comparison.csv @@ -0,0 +1,81 @@ +profile,cache_mode,trial,version,layout,ms +local-high,mtime,0,v1.2.0,module,64.035 +local-high,mtime,0,v1.2.0,workspace,62.246 +local-high,mtime,0,v1.3.0,module,62.046 +local-high,mtime,0,v1.3.0,workspace,63.526 +local-high,mtime,1,v1.3.0,module,59.856 +local-high,mtime,1,v1.3.0,workspace,59.359 +local-high,mtime,1,v1.2.0,module,60.888 +local-high,mtime,1,v1.2.0,workspace,57.78 +local-high,mtime,2,v1.2.0,module,59.513 +local-high,mtime,2,v1.2.0,workspace,58.666 +local-high,mtime,2,v1.3.0,module,60.907 +local-high,mtime,2,v1.3.0,workspace,60.677 +local-high,mtime,3,v1.3.0,module,61.057 +local-high,mtime,3,v1.3.0,workspace,66.078 +local-high,mtime,3,v1.2.0,module,59.688 +local-high,mtime,3,v1.2.0,workspace,59.945 +local-high,mtime,4,v1.2.0,module,62.602 +local-high,mtime,4,v1.2.0,workspace,60.534 +local-high,mtime,4,v1.3.0,module,60.041 +local-high,mtime,4,v1.3.0,workspace,62.872 +local-high,content,0,v1.2.0,module,74.78 +local-high,content,0,v1.2.0,workspace,58.808 +local-high,content,0,v1.3.0,module,69.964 +local-high,content,0,v1.3.0,workspace,72.634 +local-high,content,1,v1.3.0,module,70.361 +local-high,content,1,v1.3.0,workspace,73.169 +local-high,content,1,v1.2.0,module,72.674 +local-high,content,1,v1.2.0,workspace,62.133 +local-high,content,2,v1.2.0,module,71.345 +local-high,content,2,v1.2.0,workspace,63.675 +local-high,content,2,v1.3.0,module,72.413 +local-high,content,2,v1.3.0,workspace,74.242 +local-high,content,3,v1.3.0,module,70.827 +local-high,content,3,v1.3.0,workspace,72.281 +local-high,content,3,v1.2.0,module,70.191 +local-high,content,3,v1.2.0,workspace,58.963 +local-high,content,4,v1.2.0,module,75.848 +local-high,content,4,v1.2.0,workspace,62.668 +local-high,content,4,v1.3.0,module,73.313 +local-high,content,4,v1.3.0,workspace,71.006 +external-high,mtime,0,v1.2.0,module,19.355 +external-high,mtime,0,v1.2.0,workspace,19.081 +external-high,mtime,0,v1.3.0,module,18.22 +external-high,mtime,0,v1.3.0,workspace,19.227 +external-high,mtime,1,v1.3.0,module,17.882 +external-high,mtime,1,v1.3.0,workspace,19.077 +external-high,mtime,1,v1.2.0,module,17.628 +external-high,mtime,1,v1.2.0,workspace,18.073 +external-high,mtime,2,v1.2.0,module,19.328 +external-high,mtime,2,v1.2.0,workspace,18.682 +external-high,mtime,2,v1.3.0,module,18.695 +external-high,mtime,2,v1.3.0,workspace,19.012 +external-high,mtime,3,v1.3.0,module,18.834 +external-high,mtime,3,v1.3.0,workspace,17.87 +external-high,mtime,3,v1.2.0,module,19.759 +external-high,mtime,3,v1.2.0,workspace,18.436 +external-high,mtime,4,v1.2.0,module,18.746 +external-high,mtime,4,v1.2.0,workspace,18.066 +external-high,mtime,4,v1.3.0,module,19.617 +external-high,mtime,4,v1.3.0,workspace,19.569 +external-high,content,0,v1.2.0,module,19.631 +external-high,content,0,v1.2.0,workspace,19.153 +external-high,content,0,v1.3.0,module,19.407 +external-high,content,0,v1.3.0,workspace,19.739 +external-high,content,1,v1.3.0,module,18.292 +external-high,content,1,v1.3.0,workspace,21.086 +external-high,content,1,v1.2.0,module,20.028 +external-high,content,1,v1.2.0,workspace,18.68 +external-high,content,2,v1.2.0,module,19.429 +external-high,content,2,v1.2.0,workspace,18.034 +external-high,content,2,v1.3.0,module,19.94 +external-high,content,2,v1.3.0,workspace,21.173 +external-high,content,3,v1.3.0,module,20.614 +external-high,content,3,v1.3.0,workspace,21.557 +external-high,content,3,v1.2.0,module,19.51 +external-high,content,3,v1.2.0,workspace,19.053 +external-high,content,4,v1.2.0,module,20.529 +external-high,content,4,v1.2.0,workspace,18.619 +external-high,content,4,v1.3.0,module,20.633 +external-high,content,4,v1.3.0,workspace,20.922 diff --git a/docs/performance.md b/docs/performance.md new file mode 100644 index 0000000..a828f5b --- /dev/null +++ b/docs/performance.md @@ -0,0 +1,301 @@ +# Wire v1.3.0 performance + +For the two projects with 342 external packages, v1.3.0 was 84-109x faster than +Google Wire on unchanged runs and 18-19x faster after a function body edit. With +1,016 local packages and few external dependencies, an unchanged run was 9x +faster. These are generation times for test projects, not application runtime +benchmarks or a promise for every codebase. + +Compared directly with v1.2.0, no single-module case took more than 5% longer +in v1.3.0 across Go 1.25.0, 1.26.3, and 1.27.2. Some cases were faster. +Workspaces have one extra cost: +Wire now checks sibling source files that the old cache could miss. The largest +workspace measured here added 2.9 ms in default mode and 10.5 ms with opt-in +content hashing. That extra work fixes stale constructor calls. + +## Test setup + +Measured on an Apple M4 Max with 48 GiB RAM and macOS 26.5.2. Generator processes +used `GOMAXPROCS=4`, and Go builds used `-p=4`. Runs were serial, and version +order was rotated or alternated to reduce ordering effects. This was an active workstation; +small differences can come from other activity. Treat small percentage changes +as approximate with five samples per case. + +The compared sources were: + +- Google Wire: [`9c25c90`](https://github.com/google/wire/commit/9c25c9016f6825302537c4efdd5e897976f9c826). +- GoForj Wire v1.2.0: [`a64b614`](https://github.com/goforj/wire/commit/a64b6147462d563640d769c527176ed3edf14d05). +- GoForj Wire v1.3.0: [`2367f18`](https://github.com/goforj/wire/commit/2367f18afe9990c379d49864e1efc8be85ed5c65). + +The project sources come from the factories in +[`internal/wire/import_bench_test.go`](../internal/wire/import_bench_test.go). +Each has ten application features and ordinary constructors. The external +profiles import a mix of database, HTTP, Redis, and other library packages. + +| Project | Local packages | Standard library packages | External packages | +| --- | ---: | ---: | ---: | +| local | 41 | 185 | 1 | +| local-high | 1,016 | 185 | 1 | +| external-low | 42 | 240 | 342 | +| external-high | 117 | 240 | 342 | + +Counts above use Go 1.25.0 and cover packages reachable from the injector +with the `wireinject` tag. The external count includes Wire's marker package. +Both GoForj versions used the same project files and marker-package checkout. +Google Wire used the same factory inputs with its own import path. Local +replacements selected the marker packages; the generator binaries were built +from the exact source commits listed above. This isolates the generator release +comparison from changes to the application. + +The main comparison used five samples for each case, with both `mtime` (default) +and `content` cache modes. The newer-Go checks repeated unchanged, body-edit, and +constructor-edit cases on the two larger projects. In total, the comparisons +below contain **932 timed generator invocations**. Untimed setup and warmup runs +are additional. + +Building the generator and downloading modules happened before timing. For the +main comparison, `go list -export -deps -tags=wireinject` also populated Go's build +cache before timing. A fresh Wire cache therefore measures Wire startup and +cache creation without charging it for compiling all dependency export data. +Cold Go caches are measured separately below. + +Before measuring an unchanged fork run, the audit verified a generated-output +cache hit. Edit cases warmed the base state, changed one file, and then timed +regeneration. The first full pass compiled the generated projects for every +version, mode, project, and edit case. Later timing samples repeated the edits +without repeating those compilation checks. + +## Google Wire versus GoForj Wire + +Go 1.25.0, default cache mode, five-run medians. All times are milliseconds. +A fresh Wire cache starts with Go's build cache warm; subsequent rows start from +a warmed Wire cache. + +| Project | Change | Google Wire | GoForj v1.3.0 | Speedup | +| --- | --- | ---: | ---: | ---: | +| external-high | Fresh Wire cache | 1,600.3 | 1,571.7 | 1.02x | +| external-high | Unchanged | 1,582.0 | 18.9 | 83.71x | +| external-high | Function body edit | 1,580.0 | 87.3 | 18.11x | +| external-high | Constructor argument added | 1,604.8 | 262.6 | 6.11x | +| external-high | Import added | 1,567.2 | 267.8 | 5.85x | +| external-high | Return to previous imports | 1,573.3 | 275.0 | 5.72x | +| external-low | Fresh Wire cache | 1,626.6 | 1,540.9 | 1.06x | +| external-low | Unchanged | 1,581.0 | 14.5 | 109.33x | +| external-low | Function body edit | 1,579.9 | 81.4 | 19.41x | +| external-low | Constructor argument added | 1,580.2 | 242.3 | 6.52x | +| external-low | Import added | 1,565.3 | 243.1 | 6.44x | +| external-low | Return to previous imports | 1,564.6 | 244.2 | 6.41x | +| local-high | Fresh Wire cache | 558.0 | 713.8 | 0.78x | +| local-high | Unchanged | 544.1 | 60.2 | 9.03x | +| local-high | Function body edit | 543.3 | 132.7 | 4.09x | +| local-high | Constructor argument added | 535.0 | 407.3 | 1.31x | +| local-high | Import added | 521.9 | 408.3 | 1.28x | +| local-high | Return to previous imports | 537.9 | 413.5 | 1.30x | +| local | Fresh Wire cache | 401.7 | 378.1 | 1.06x | +| local | Unchanged | 394.7 | 9.3 | 42.47x | +| local | Function body edit | 391.7 | 26.8 | 14.59x | +| local | Constructor argument added | 402.6 | 100.9 | 3.99x | +| local | Import added | 398.1 | 99.9 | 3.98x | +| local | Return to previous imports | 396.0 | 102.0 | 3.88x | + +The 1,016-local-package project is a useful limit on the claim. Its first run +with a fresh Wire cache was slower than Google Wire. Reruns were faster, but +constructor and import edits had much smaller gains than unchanged runs. + +## v1.3.0 versus v1.2.0 + +Go 1.25.0, five-run medians. Positive changes mean v1.3.0 took longer. Both +versions used identical project inputs and started each case with the same kind +of cache state. Small differences should be read alongside their absolute cost. + +### Default cache mode + +| Project | Change | v1.2.0 (ms) | v1.3.0 (ms) | Change | +| --- | --- | ---: | ---: | ---: | +| external-high | Fresh Wire cache | 1,550.6 | 1,571.7 | +1.4% | +| external-high | Unchanged | 18.4 | 18.9 | +2.8% | +| external-high | Function body edit | 87.5 | 87.3 | -0.2% | +| external-high | Constructor argument added | 258.3 | 262.6 | +1.6% | +| external-high | Import added | 269.8 | 267.8 | -0.8% | +| external-high | Return to previous imports | 270.4 | 275.0 | +1.7% | +| external-low | Fresh Wire cache | 1,523.7 | 1,540.9 | +1.1% | +| external-low | Unchanged | 14.7 | 14.5 | -1.3% | +| external-low | Function body edit | 80.2 | 81.4 | +1.6% | +| external-low | Constructor argument added | 241.3 | 242.3 | +0.4% | +| external-low | Import added | 247.2 | 243.1 | -1.6% | +| external-low | Return to previous imports | 244.5 | 244.2 | -0.1% | +| local-high | Fresh Wire cache | 737.1 | 713.8 | -3.2% | +| local-high | Unchanged | 63.1 | 60.2 | -4.5% | +| local-high | Function body edit | 135.8 | 132.7 | -2.3% | +| local-high | Constructor argument added | 420.1 | 407.3 | -3.1% | +| local-high | Import added | 408.6 | 408.3 | -0.1% | +| local-high | Return to previous imports | 414.6 | 413.5 | -0.3% | +| local | Fresh Wire cache | 379.7 | 378.1 | -0.4% | +| local | Unchanged | 9.1 | 9.3 | +2.2% | +| local | Function body edit | 27.4 | 26.8 | -1.9% | +| local | Constructor argument added | 99.9 | 100.9 | +1.0% | +| local | Import added | 103.0 | 99.9 | -3.0% | +| local | Return to previous imports | 101.3 | 102.0 | +0.7% | + +### Content-hash cache mode + +| Project | Change | v1.2.0 (ms) | v1.3.0 (ms) | Change | +| --- | --- | ---: | ---: | ---: | +| external-high | Fresh Wire cache | 1,884.4 | 1,853.2 | -1.7% | +| external-high | Unchanged | 20.0 | 20.0 | -0.0% | +| external-high | Function body edit | 148.3 | 142.1 | -4.2% | +| external-high | Constructor argument added | 314.6 | 313.3 | -0.4% | +| external-high | Import added | 326.2 | 320.1 | -1.9% | +| external-high | Return to previous imports | 197.8 | 201.1 | +1.7% | +| external-low | Fresh Wire cache | 1,812.7 | 1,838.4 | +1.4% | +| external-low | Unchanged | 14.9 | 15.2 | +1.6% | +| external-low | Function body edit | 136.3 | 135.3 | -0.8% | +| external-low | Constructor argument added | 299.2 | 299.3 | +0.1% | +| external-low | Import added | 301.4 | 300.5 | -0.3% | +| external-low | Return to previous imports | 181.1 | 178.0 | -1.7% | +| local-high | Fresh Wire cache | 793.0 | 802.4 | +1.2% | +| local-high | Unchanged | 70.8 | 71.3 | +0.8% | +| local-high | Function body edit | 167.7 | 171.9 | +2.5% | +| local-high | Constructor argument added | 430.8 | 439.9 | +2.1% | +| local-high | Import added | 432.1 | 439.4 | +1.7% | +| local-high | Return to previous imports | 329.7 | 338.8 | +2.8% | +| local | Fresh Wire cache | 448.7 | 445.4 | -0.7% | +| local | Unchanged | 9.7 | 10.1 | +4.6% | +| local | Function body edit | 42.8 | 41.9 | -2.2% | +| local | Constructor argument added | 115.1 | 116.1 | +0.8% | +| local | Import added | 116.1 | 118.4 | +2.0% | +| local | Return to previous imports | 83.2 | 85.6 | +2.8% | + +The main matrix has 600 timings and 100 successful generation/compilation checks. +Its raw samples are in [release-comparison-go1.25.csv](benchmarks/release-comparison-go1.25.csv). + +## Go 1.26 and Go 1.27 + +The two larger projects were also checked with both releases built using Go +1.26.3 and Go 1.27.2. Each row is the median of five samples. These runs covered +both cache modes and added 240 timings and 48 compilation checks. + +| Go | Project | Cache mode | Change | v1.2.0 (ms) | v1.3.0 (ms) | Change | +| --- | --- | --- | --- | ---: | ---: | ---: | +| 1.26.3 | local-high | mtime | Unchanged | 62.6 | 65.0 | +3.8% | +| 1.26.3 | local-high | mtime | Function body edit | 140.0 | 140.1 | +0.1% | +| 1.26.3 | local-high | mtime | Constructor argument added | 423.1 | 419.3 | -0.9% | +| 1.26.3 | local-high | content | Unchanged | 73.3 | 74.4 | +1.6% | +| 1.26.3 | local-high | content | Function body edit | 173.4 | 173.7 | +0.2% | +| 1.26.3 | local-high | content | Constructor argument added | 443.1 | 448.7 | +1.3% | +| 1.26.3 | external-high | mtime | Unchanged | 19.6 | 19.2 | -2.0% | +| 1.26.3 | external-high | mtime | Function body edit | 89.7 | 87.4 | -2.6% | +| 1.26.3 | external-high | mtime | Constructor argument added | 268.7 | 274.6 | +2.2% | +| 1.26.3 | external-high | content | Unchanged | 20.6 | 20.5 | -0.5% | +| 1.26.3 | external-high | content | Function body edit | 151.4 | 150.0 | -0.9% | +| 1.26.3 | external-high | content | Constructor argument added | 327.0 | 327.7 | +0.2% | +| 1.27.2 | local-high | mtime | Unchanged | 61.4 | 63.0 | +2.7% | +| 1.27.2 | local-high | mtime | Function body edit | 141.1 | 139.3 | -1.2% | +| 1.27.2 | local-high | mtime | Constructor argument added | 413.2 | 421.2 | +1.9% | +| 1.27.2 | local-high | content | Unchanged | 71.4 | 71.5 | +0.1% | +| 1.27.2 | local-high | content | Function body edit | 186.5 | 178.9 | -4.1% | +| 1.27.2 | local-high | content | Constructor argument added | 449.6 | 439.7 | -2.2% | +| 1.27.2 | external-high | mtime | Unchanged | 20.4 | 21.4 | +5.0% | +| 1.27.2 | external-high | mtime | Function body edit | 95.2 | 93.0 | -2.3% | +| 1.27.2 | external-high | mtime | Constructor argument added | 308.4 | 305.1 | -1.1% | +| 1.27.2 | external-high | content | Unchanged | 22.7 | 21.0 | -7.5% | +| 1.27.2 | external-high | content | Function body edit | 150.9 | 153.8 | +1.9% | +| 1.27.2 | external-high | content | Constructor argument added | 352.2 | 358.9 | +1.9% | + +Raw samples: [newer-go-comparison.csv](benchmarks/newer-go-comparison.csv). + +## Fully cold Go caches + +These are first generation runs with a fresh Go build cache and a fresh Wire +cache. Module downloads and the generator build are still excluded. Each value +is the median of three samples, with version order alternated. Go 1.25.0, +default cache mode. + +| Project | v1.2.0 | v1.3.0 | Change | +| --- | ---: | ---: | ---: | +| local-high | 7.28 s | 7.44 s | +2.1% | +| external-high | 10.16 s | 10.22 s | +0.6% | + +Cold starts are a real cost. The repository's separate three-sample scenario +runner measured Google Wire at 0.75 s versus GoForj at 7.27 s for `local-high`, +and 2.36 s versus 10.28 s for `external-high`, with fresh Go/Wire caches. The +release comparison above shows that the cold-start cost was already present +in v1.2.0. The large speedups apply after caches are populated. + +Raw samples: [cold-go-cache.csv](benchmarks/cold-go-cache.csv). + +## Generation from a separate tools module + +The same two projects were measured from their own module and from a separate +tools module in a `go.work` workspace. Before timing, the audit warmed the cache +and checked for an output-cache hit. Each row has five samples, with compilation +checked on the first pass. Go 1.25.0. These checks added 80 timings and 16 +compilation checks. + +| Project | Cache mode | Run from | v1.2.0 (ms) | v1.3.0 (ms) | Change | +| --- | --- | --- | ---: | ---: | ---: | +| local-high | mtime | module | 60.9 | 60.9 | +0.0% | +| local-high | mtime | workspace | 59.9 | 62.9 | +4.9% | +| local-high | content | module | 72.7 | 70.8 | -2.5% | +| local-high | content | workspace | 62.1 | 72.6 | +16.9% | +| external-high | mtime | module | 19.3 | 18.7 | -3.3% | +| external-high | mtime | workspace | 18.4 | 19.1 | +3.5% | +| external-high | content | module | 19.6 | 19.9 | +1.6% | +| external-high | content | workspace | 18.7 | 21.1 | +12.9% | + +For `local-high`, default workspace reruns increased by 2.9 ms. With content +hashing they increased by 10.5 ms, about 17%. The smaller set of local files in +`external-high` added 0.6 ms and 2.4 ms respectively. + +The extra work matters for correctness. v1.2.0 could reuse old output after a +constructor changed in another workspace module, leaving code that no longer +compiled. v1.3.0 checks those files before reusing its output. Content hashing +reads their contents on each run, so it pays more than the default file-metadata +check. These are measured costs, not a claim of zero overhead. + +Raw samples: [workspace-comparison.csv](benchmarks/workspace-comparison.csv). + +## Correctness checks + +- All 164 generation/compilation checks in the comparisons passed. +- The full repository tests passed on Go 1.25.0 with the race detector, and on Go 1.26.3 and 1.27.2. +- `go vet ./...` passed on Go 1.25.0. +- The published v1.3.0 tool was installed through the Go module proxy without a local Wire replacement. Both cache modes regenerated and compiled two workspace targets after removing a constructor argument and its options type. +- The workspace regression test also checks that a newly missing dependency produces an error after a successful cache warmup. + +See [`workspace_cache_test.go`](../internal/wire/workspace_cache_test.go) for the +workspace/local-replacement correctness checks. The ordinary module benchmarks +used `GOWORK=off`; only the workspace-specific checks enabled a workspace. + +## Running the repository benchmarks + +For the application-shaped inputs: + +```sh +bash scripts/import-benchmarks.sh scenarios +``` + +For the small import-only inputs: + +```sh +bash scripts/import-benchmarks.sh table +``` + +The import-only test uses small constructors with few standard library or +external imports. Its 2-6x speedups measure a different kind of input from the +application tests above. Package count alone does not tell you how much work a +cache hit saves. + +The checked-in scenario runner reports three-sample medians and includes fresh +Go build caches for its cold-run row. The five-sample release comparison in this +report adds an explicit export-data warmup, rotates release order, checks both +cache modes, and compiles edited outputs. Its `Return to previous imports` row +removes the import added by the preceding step; the repository runner's `known +import toggle` row instead returns from a constructor/import shape change. Those +rows should not be treated as identical tests. + +To repeat a comparison between releases, use the same generated project files, +Go version, thread limit, and cache settings for both binaries. Measure fresh +Wire caches separately from fresh Go build caches. Warm past the creation of +`wire_gen.go` before timing unchanged runs, and compile the output after changing +constructors. A fast result that leaves stale code is not a successful run.