Skip to content

perf: guard loggerExternal.entering/exiting with isLoggable(FINER) across the driver#2955

Open
Ananya2 wants to merge 9 commits into
mainfrom
pr2945-logging-guard-resultset
Open

perf: guard loggerExternal.entering/exiting with isLoggable(FINER) across the driver#2955
Ananya2 wants to merge 9 commits into
mainfrom
pr2945-logging-guard-resultset

Conversation

@Ananya2
Copy link
Copy Markdown
Contributor

@Ananya2 Ananya2 commented May 14, 2026

Summary

Extends PR #2945 (which guarded SQLServerResultSet) to the rest of the driver by adding isLoggable(Level.FINER) guards around 640 previously-unguarded loggerExternal.entering(...) / loggerExternal.exiting(...) call sites across 13 driver classes. When logging is disabled (the common production configuration), the unguarded variants still incur primitive autoboxing (int → Integer, boolean → Boolean, etc.) for the varargs Object... parameter, Object[] allocations on multi-argument call sites, virtual dispatch into Logger.entering(...) / Logger.exiting(...), and an internal isLoggable(FINER) check before immediately returning. After this change, the explicit guard short-circuits all of that work whenever the logger level is above FINER (the default).

Change

Applied mechanically across the remaining driver classes, including SQLServerCallableStatement.java (235 wrapped call sites), SQLServerPreparedStatement.java (115), SQLServerConnection.java (112), SQLServerStatement.java (99), SQLServerDataSource.java (31), SQLServerBulkCopy.java (23), SQLServerDriver.java (12), SQLServerBulkRecord.java (6), SQLServerBulkCSVFileRecord.java (5), and SQLServerBulkBatchInsertRecord.java (2), for a total of 640 newly-guarded entering(...) / exiting(...) call sites.

Every existing:

loggerExternal.entering(...);
loggerExternal.exiting(...);

is now wrapped in:

if (loggerExternal.isLoggable(Level.FINER)) {
    ...
}

There is no behavioral change; logging output remains identical whenever FINER logging is enabled. Already-guarded sites (833 total across these files) were intentionally left untouched — existing isLoggable(...) checks are detected and skipped automatically. Additionally, fully-qualified java.util.logging.Level.FINER references were replaced with the imported Level.FINER form for consistency with surrounding code, with no behavioral or bytecode impact.

Performance Impact

The performance benefit is concentrated in per-row / per-column / per-parameter hot paths where the JIT cannot eliminate boxing and varargs allocations across the java.util.logging.Logger boundary.

Benchmark Results
Driver Fetch Size Avg (ms) Min (ms) Max (ms) Runs
Baseline (Microsoft) default (128) 52,424 48,039 66,302 60
Baseline (Microsoft) 512 51,433 48,038 64,474 60
Perf-Fix (Microsoft) default (128) 50,999 46,701 62,621 69
Perf-Fix (Microsoft) 512 50,628 46,732 66,539 60
Comparison Result
Perf-Fix vs Baseline ~2.7% faster
Interpretation
SQLServerPreparedStatement / SQLServerCallableStatement show the most realistic gains due to heavy parameter-binding paths.
SQLServerBulkCopy / SQLServerBulk*Record see smaller wins because TDS encoding still dominates total runtime.
SQLServerConnection, SQLServerStatement, SQLServerDriver, and SQLServerDataSource are included primarily for consistency; these are connection/query-frequency paths rather than row-frequency paths.

The wall-clock improvement is modest because network round-trips and TDS parsing dominate overall execution time.

The larger benefit is reduced young-generation allocation pressure and GC churn under sustained workloads, which is more visible under allocation profiling than end-to-end latency benchmarks.

For reference, PR #2945 previously measured ~1.82× improvement on a narrow mixed-type SQLServerResultSet benchmark after applying the same optimization pattern.

Risk

  • No public API change.
  • Logging output is unchanged when FINER is enabled (the guard predicate is exactly the same threshold Logger.entering() internally checks).
  • Mechanical/script-generated transformation only.
  • No loggerExternal.fine(...), finer(...), log(...), etc. calls were modified — only entering(...) / exiting(...)

saurabh500 and others added 6 commits May 9, 2026 01:22
Wrap 396 unguarded loggerExternal.entering() and exiting() calls in
SQLServerResultSet with isLoggable(Level.FINER) checks.

When logging is disabled (the common production case), this eliminates:
- Autoboxing of primitive parameters (int -> Integer) for varargs
- Object[] array creation for multi-arg entering/exiting calls
- getClassNameLogging() call overhead

Benchmarked with 10M iterations on JDK 21:
  Unguarded: 47.4ms  Guarded: 24.2ms  (~2x faster per getter call)

For a typical query reading 1M rows x 10 columns, this eliminates
~20M unnecessary autoboxing allocations and array creations.
Single-file, zero-dependency benchmark that demonstrates the impact of
guarding entering/exiting calls with isLoggable(FINER) in ResultSet getters.

Compile and run: javac LoggerGuardBenchmark.java && java LoggerGuardBenchmark
Resolved conflicts in SQLServerResultSet, SQLServerCallableStatement, and SQLServerPreparedStatement by taking origin/main's content and re-applying the loggerExternal.entering/exiting isLoggable(Level.FINER) guards. Line endings preserved per-file to match origin/main convention (LF for most files, CRLF for ScrollWindow/SimpleInputStream/SQLServerConnectionPoolProxy).
@Ananya2 Ananya2 force-pushed the pr2945-logging-guard-resultset branch from 1ddc8ba to 787a02e Compare May 14, 2026 14:48
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 42.66389% with 551 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.30%. Comparing base (4af91fe) to head (7e3893b).

Files with missing lines Patch % Lines
...oft/sqlserver/jdbc/SQLServerPreparedStatement.java 35.91% 32 Missing and 175 partials ⚠️
...m/microsoft/sqlserver/jdbc/SQLServerStatement.java 41.66% 59 Missing and 67 partials ⚠️
.../microsoft/sqlserver/jdbc/SQLServerConnection.java 53.46% 17 Missing and 97 partials ⚠️
.../microsoft/sqlserver/jdbc/SQLServerDataSource.java 50.70% 6 Missing and 29 partials ⚠️
...om/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java 45.09% 0 Missing and 28 partials ⚠️
...oft/sqlserver/jdbc/SQLServerBulkCSVFileRecord.java 0.00% 6 Missing and 8 partials ⚠️
.../microsoft/sqlserver/jdbc/SQLServerBulkRecord.java 0.00% 14 Missing ⚠️
.../com/microsoft/sqlserver/jdbc/SQLServerDriver.java 66.66% 0 Missing and 7 partials ⚠️
...sqlserver/jdbc/SQLServerBulkBatchInsertRecord.java 0.00% 2 Missing and 4 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2955      +/-   ##
============================================
- Coverage     60.83%   59.30%   -1.54%     
- Complexity     4980     5041      +61     
============================================
  Files           151      151              
  Lines         35223    36253    +1030     
  Branches       5900     6626     +726     
============================================
+ Hits          21429    21499      +70     
- Misses        10932    11047     +115     
- Partials       2862     3707     +845     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies the logging optimization from #2945 across additional Microsoft JDBC Driver classes by guarding loggerExternal.entering(...) / loggerExternal.exiting(...) call sites with loggerExternal.isLoggable(Level.FINER) to avoid unnecessary varargs allocations and boxing when FINER logging is disabled.

Changes:

  • Wrapped many previously-unguarded loggerExternal.entering/exiting calls with isLoggable(Level.FINER) checks.
  • Standardized some logging-level references from fully-qualified java.util.logging.Level.FINER to Level.FINER (with corresponding imports where needed).

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java Guards loggerExternal.entering/exiting calls in statement execution and property accessors.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Guards loggerExternal.entering/exiting across parameter-binding and execution paths.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java Guards loggerExternal.entering/exiting for driver entry points and version/compliance methods.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java Guards loggerExternal.entering/exiting across DataSource getters/setters and property helpers.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java Guards loggerExternal.entering/exiting across connection lifecycle and statement factory methods.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkRecord.java Adds FINER guards around bulk-record entering/exiting and imports Level.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCSVFileRecord.java Adds FINER guards around entering/exiting in constructors/close/metadata and imports Level.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java Adds FINER guards around bulk-copy lifecycle and configuration methods.
src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkBatchInsertRecord.java Adds FINER guards around entering/exiting and imports Level.
Comments suppressed due to low confidence (4)

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java:8138

  • prepareCall(String, int, int, int, SQLServerStatementColumnEncryptionSetting) logs loggerExternal.entering(..., "prepareStatement", ...), which misidentifies the method in FINER traces. Update the logged method name to "prepareCall".
    public CallableStatement prepareCall(String sql, int nType, int nConcur, int resultSetHoldability,
            SQLServerStatementColumnEncryptionSetting stmtColEncSetiing) throws SQLServerException {
        if (loggerExternal.isLoggable(Level.FINER)) {
            loggerExternal.entering(loggingClassName, "prepareStatement",
                    new Object[] {nType, nConcur, resultSetHoldability, stmtColEncSetiing});
        }

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java:1629

  • getStringProperty performs if (loggerExternal.isLoggable(Level.FINER) && ...) and then immediately re-checks loggerExternal.isLoggable(Level.FINER) before calling exiting(...). The inner check is redundant; remove it to reduce clutter and minor overhead.
        if (loggerExternal.isLoggable(Level.FINER) && !propKey.contains("password")
                && !propKey.contains("Password"))
            if (loggerExternal.isLoggable(Level.FINER)) {
                loggerExternal.exiting(getClassNameLogging(), "get" + propKey, propValue);
            }

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java:1568

  • getMinorVersion() has two consecutive loggerExternal.isLoggable(Level.FINER) checks surrounding entering/exiting with no intervening work. Consolidate to a single guard/cached boolean to reduce redundancy and improve readability.
    public int getMinorVersion() {
        if (loggerExternal.isLoggable(Level.FINER)) {
            loggerExternal.entering(getClassNameLogging(), "getMinorVersion");
        }
        if (loggerExternal.isLoggable(Level.FINER)) {
            loggerExternal.exiting(getClassNameLogging(), "getMinorVersion", SQLJdbcVersion.MINOR);
        }

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java:1584

  • jdbcCompliant() has two consecutive loggerExternal.isLoggable(Level.FINER) checks around entering/exiting with no intervening work. Use a single guard (or cached boolean) for both calls to avoid redundant isLoggable checks.
    @Override
    public boolean jdbcCompliant() {
        if (loggerExternal.isLoggable(Level.FINER)) {
            loggerExternal.entering(getClassNameLogging(), "jdbcCompliant");
        }
        if (loggerExternal.isLoggable(Level.FINER)) {
            loggerExternal.exiting(getClassNameLogging(), "jdbcCompliant", Boolean.TRUE);
        }

Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java Outdated
Comment thread src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

4 participants