diff --git a/api/src/main/java/com/google/common/flogger/LogContext.java b/api/src/main/java/com/google/common/flogger/LogContext.java index 49156d8c..e27ff8b8 100644 --- a/api/src/main/java/com/google/common/flogger/LogContext.java +++ b/api/src/main/java/com/google/common/flogger/LogContext.java @@ -525,16 +525,22 @@ protected boolean postProcess(@NullableDecl LogSiteKey logSiteKey) { // Without a log site we ignore any log-site specific behaviour. if (logSiteKey != null) { // Don't "return true" early from this code since we also need to handle stack size. + // Only get the stats instance when we need it, but cache it if we do. This avoids getting + // an instance for every log statement when the vast majority don't need it. + LogSiteStats stats = null; Integer rateLimitCount = metadata.findValue(Key.LOG_EVERY_N); - RateLimitPeriod rateLimitPeriod = metadata.findValue(Key.LOG_AT_MOST_EVERY); - LogSiteStats stats = LogSiteStats.getStatsForKey(logSiteKey, metadata); - if (rateLimitCount != null && !stats.incrementAndCheckInvocationCount(rateLimitCount)) { - return false; + if (rateLimitCount != null) { + stats = ensureStats(stats, logSiteKey, metadata); + if (!stats.incrementAndCheckInvocationCount(rateLimitCount)) { + return false; + } } - - if (rateLimitPeriod != null - && !stats.checkLastTimestamp(getTimestampNanos(), rateLimitPeriod)) { - return false; + RateLimitPeriod rateLimitPeriod = metadata.findValue(Key.LOG_AT_MOST_EVERY); + if (rateLimitPeriod != null) { + stats = ensureStats(stats, logSiteKey, metadata); + if (!stats.checkLastTimestamp(getTimestampNanos(), rateLimitPeriod)) { + return false; + } } } @@ -568,6 +574,16 @@ protected boolean postProcess(@NullableDecl LogSiteKey logSiteKey) { return true; } + // Helper to get the stats instance on demand while reusing an instance if already obtained. + // Usage: + // // Possible null stats here... + // stats = ensureStats(stats, logSiteKey, metadata); + // // Non-null stats here (assigned to variable for next time) + private static LogSiteStats ensureStats( + @NullableDecl LogSiteStats stats, LogSiteKey logSiteKey, Metadata metadata) { + return stats != null ? stats : LogSiteStats.getStatsForKey(logSiteKey, metadata); + } + /** * Pre-processes log metadata and determines whether we should make the pending logging call. *