guava — Engineering Performance
3 engineers all time · Jan 2025 – Aug 2026 · built 2026-08-23 · GitHub
Performance snapshot
Today's rolling 90-day reading for guava, compared with the start of the series. Pick a window to move that comparison point.
Eff. capacity added
+11.1engineers
3 devs deliver like 14 (4.7x pre-AI)
Avg. perf / dev / mo (ETV)
+84.1%
2.20 → 4.05
Active engineers
±0%
3.0 → 3.0
Features
−2.3pp
3.8% → 1.5%
guava vs. Google
Per-engineer ETV for guava against Google as a whole. Both lines are 90-day rolling averages scaled to a 30-day month, so they share one axis and can be read against each other at any point. Pick a window to zoom the chart to it.
Performance over time
ETV stacked by Features / Maintenance / Tests / Docs / Fixes — 90-day moving average, normalized to ETV / month.
Engineering capacity
Effective engineers behind guava, in pre-AI terms. Per-engineer ETV divided by the Q1 2025 baseline of 0.86 ETV / dev / mo gives a capacity multiple, and that multiple applied to the engineers active in the trailing 90 days turns it into engineer-equivalents. The line is the real headcount, so the gap between line and area is what the leverage is worth.
Knowledge concentration
How dependent is this repo on a small number of engineers? Higher top-1 share = higher key-person risk.
cpovirk owns 88.5 % of commits.
Reports
Written summary of the work completed each month.
No monthly reports available yet.
Top engineers
Most impactful commits
Top 10 by ETV in the all-time window.
- 7.7ETVAddress some more counterfactual [CheckedExceptionNotThrown](https://errorprone.info/bugpattern/CheckedExceptionNotThrown) findings. I suspect that IntelliJ flags most of these, especially since its analyses seem happy to treat Guava as a "closed world" with no callers/overrides outside the project, if I'm remembering right. Anyway, that makes them nice to fix so that F2 doesn't jump to them. We don't normally worry much about a stray `throws Exception` on a `test*` method in particular, but it was easier to have the tooling remove them (and then glance over the results) than to make it smarter, and it's a nice bonus to remove such `throws` clauses, anyway. It's possible that I could rerun this cleanup until I reach a fixed point, since each removal may unlock removals downstream. I think that I made one follow-up change somewhere in `util.concurrent`. Maybe I'll do another "full" round, maybe using IntelliJ in case it catches anything that Error Prone did not. I made no effort to look at `abstract` methods that might have no implementations that actually throw a declared exception. I made no effort to remove calls to `super.setUp`/`tearDown` when those calls are no-ops (because they call the methods on plain `TestCase`). If I were to do so, that might unlock more `throws` removals on the `setUp` and `tearDown` methods that are making those calls. There were some cases that I had to revert: - `TypeTokenTest.CannotConstruct` constructor - `AbstractIdleService`: `DefaultService` and `TestService`, both `startUp` and `shutDown` (though I may or may not have needed to revert all four) - `AbstractExecutionThreadServiceTest.FakeServices.startUp` Finally, I made `ListeningExecutorServiceTest.FakeExecutorService` `final` while I was in the area. RELNOTES=n/a PiperOrigin-RevId: 938063962cpovirk · c37cd2ae · 2026-06-25
- 4.2ETVRemove unnecessary type arguments. This CL comes courtesy of IntelliJ. (I did revert a few files that ended up with errors, probably often from non-javac tools like our transpilers, and I reverted one tiny part of `OrderingTest`. I may have been able to get away with reverting less.) (previously: https://github.com/google/guava/commit/cb0e7e0cb1c62012934d998ca4d0222a758a9831, https://github.com/google/guava/commit/c1ffb313fd084c865e539c9b6dc795edade21d6a, https://github.com/google/guava/commit/35a4ccbcbb86952f1c021424acd70c7526e8964d, https://github.com/google/guava/commit/08f213923dab324b53a5ee93151a2a2c04be0784, https://github.com/google/guava/commit/274062cdc2a3819ff4b0286e57973b1bbe8c8519, which together explain why I'm not seeing hits in the prod code for packages like `collect`) RELNOTES=n/a PiperOrigin-RevId: 906444162cpovirk · b16d0611 · 2026-04-27
- 2.7ETVMark test-suite-builder suites and related code as `@AndroidIncompatible`. (Along the way, break out `SynchronizedSetTest.TestSet` into a top-level type `LockHeldAssertingSet`, which should also make it easier to run each test in an individual build target someday.) (I did also sneak in one change to the backport copy of `IteratorsTest`. It resolve a diff that we accidentally introduced in cl/613629330.) Such code is already not run when we run our tests under Android emulators. (The Android JUnit 3 runner just ignores `suite()` methods, I want to say?) However, it's still _built_ for them. Besides being a waste, this requires pulling in the whole suite-builder ecosystem, which is again causing problems when I try to bump various things related to Android version—quite possibly a sign that the Android runner starts actually using `suite()` methods, whose large numbers of tests (at least in `common.collect`) are just too much for that environment? By adding `@AndroidIncompatible`, I configure our Android test build to strip the code altogether. RELNOTES=n/a PiperOrigin-RevId: 719651707cpovirk · 1d3cbf82 · 2025-01-25
- 2.5ETVUse most of the main `AbstractFuture` implementation from J2KT and from GWT/J2CL. This CL introduces a superclass, `AbstractFutureState`, following the pattern of [`AggregateFutureState`](https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/AggregateFutureState.java). That superclass contains platform-specific operations. Fixes https://github.com/google/guava/issues/2934 RELNOTES=n/a PiperOrigin-RevId: 729328833cpovirk · b15c23fb · 2025-02-21
- 2.4ETVUse `assertThrows` more. I addressed the resulting https://errorprone.info/bugpattern/AssertThrowsMinimizer warnings where I saw them in an early snapshot. But I seem to be seeing them at different places at different times, so I'm leaving some that I'll get in a future round. Also, add two missing(?) tests of `clear()` in backport copy of `MapsTest.ensureNotDirectlyModifiable`. RELNOTES=n/a PiperOrigin-RevId: 895922607cpovirk · 04098aa3 · 2026-04-07
- 2.4ETVStandardize racy lazy init. This addresses almost all our https://errorprone.info/bugpattern/AssignmentExpression warnings. The final(?) warnings will be addressed by cl/959862978. RELNOTES=n/a PiperOrigin-RevId: 962152630cpovirk · b811c779 · 2026-08-10
- 2.2ETVAddress various findings, mostly from IntelliJ. Most of the findings are around Javadoc links to non-visible APIs. The mildly annoying case is when we write something like `{@link #keySet}`: If we were building Javadoc with the `-private` flag, then these references would be to the private field of that name. And that's... probably fine, since the rendered Javadoc is in fact going to include private members? But I guess it's questionable to refer to private members of another class at all, even from within Javadoc? Anyway, when we run plain old Javadoc, the links get resolved to `keySet()`, as desired. So the changes of that nature are about making IntelliJ happy (so that I can jump from "real error" to "real error" more easily in cl/934353699) and maybe being slightly more principled about things, rather than fixing errors in our rendered Javadoc. (Also notice that plenty of the findings were in `javatests`, which we don't normally generate Javadoc for.) A couple other notes on Javadoc: - I stopped trying to link to `EmptyImmutableTable`, which was deleted in cl/43207266. There may well have been some other deletions (or at least moves, like `hashFloodingDetected`, mentioned in `ImmutableSetHashFloodingDetectionBenchmark`) that I didn't dig into or at least didn't save notes on. - I made the Android flavor of `TopKSelector` refer to `Comparators.least`, eliminating a diff from the mainline, since we added `least` to the Android flavor a while back. The other notable class of findings is unnecessary casts. RELNOTES=n/a PiperOrigin-RevId: 934979370cpovirk · 4b0974be · 2026-06-19
- 2.2ETVRefactor the main `AbstractFuture` implementation to prepare for using it for more environments. That includes J2KT and [GWT/J2CL](https://github.com/google/guava/issues/2934). Changes include: - Suppress nullness at smaller scopes, fixing errors that were hidden by the old, broad suppression. - Remove `synchronized` from an override of `fillInStackTrace`. J2KT doesn't like `synchronized` except on very specific types, and we don't need it. - Introduce `rethrowIfErrorOtherThanStackOverflow` and `interruptCurrentThread`, `Platform` methods that will require different implementations for J2KT and J2CL/GWT. - Introduce helper methods like `casListeners(expect, update)` for `AtomicHelper` operations. These reduce verbosity relative to `ATOMIC_HELPER.casListeners(this, expect, update)`. They also prepare for `AbstractFuture` implementations that don't use `AtomicHelper`. - Introduce `notInstanceOfSetFuture`. This is arguably nicer than `!(localValue instanceof SetFuture)`, but the real purpose is to prepare for when code in a different file needs to check `instance SetFuture`. (I could be convinced that I should just make `SetFuture` package-private instead, even though no one outside the file should use it for anything but an `instanceof` check.) - Mysteriously move things around, increase visibility of members, and introduce and sometimes use accessors. This is to prepare for when some of the code will be moving to a separate file so that the remainder of `AbstractFuture` can be wholly shared across different platforms. - Fix a few typos in comments. Also, rename `SetFuture`. This isn't directly related, but now is as good a time as any to do it. Additional bonus: This CL probably makes [the logging at the "end" of `AbstractFuture` static initialization](https://github.com/google/guava/blob/7ec362ec68b630363231d5292cd6b2577c710be6/guava/src/com/google/common/util/concurrent/AbstractFuture.java#L210) have a better chance of actually working in the hypothetical situation that a logger uses `AbstractFuture`: Currently, `AbstractFuture` performs some further initialization _after_ that logging (such as the initialization of `NULL`). Now, it performs all that initialization before the `static` block that might log. RELNOTES=n/a PiperOrigin-RevId: 729313044cpovirk · 2dd82ad9 · 2025-02-21
- 2.2ETVMigrate parts of `javatests/com/google/common/testing/...` from JUnit3 to JUnit4, so that we can use `TestParameterInjector` in an upcoming CL. RELNOTES=n/a PiperOrigin-RevId: 938246066Kurt Alfred Kluever · 6dc67972 · 2026-06-25
- 2.0ETVUse _more_ lambdas. RELNOTES=n/a PiperOrigin-RevId: 725740741cpovirk · c282d6a6 · 2025-02-11