Skip to content

Commit f08338e

Browse files
committed
perf(pool): optimize TryTransition to reduce atomic operations
Further optimize the hot path by: 1. Remove redundant GetState() call in the loop 2. Only check waiterCount after successful CAS (not before loop) 3. Inline the waiterCount check to avoid notifyWaiters() call overhead This reduces atomic operations from 4-5 per Get/Put to 2-3: - Before: GetState() + CAS + waiterCount.Load() + notifyWaiters mutex check - After: CAS + waiterCount.Load() (only if CAS succeeds) Performance impact: - Eliminates 1-2 atomic operations per Get/Put - Expected improvement: ~10-15% for Get/Put operations
1 parent 374acc3 commit f08338e

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

internal/pool/conn_state.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,15 @@ func (sm *ConnStateMachine) TryTransition(validFromStates []ConnState, targetSta
133133
// Try each valid from state with CAS
134134
// This ensures only ONE goroutine can successfully transition at a time
135135
for _, fromState := range validFromStates {
136-
// Fast path: check if we're already in target state
137-
if fromState == targetState && sm.GetState() == targetState {
138-
return targetState, nil
139-
}
140-
141136
// Try to atomically swap from fromState to targetState
142137
// If successful, we won the race and can proceed
143138
if sm.state.CompareAndSwap(uint32(fromState), uint32(targetState)) {
144139
// Success! We transitioned atomically
145-
// Notify any waiters
146-
sm.notifyWaiters()
140+
// Hot path optimization: only check for waiters if transition succeeded
141+
// This avoids atomic load on every Get/Put when no waiters exist
142+
if sm.waiterCount.Load() > 0 {
143+
sm.notifyWaiters()
144+
}
147145
return targetState, nil
148146
}
149147
}

0 commit comments

Comments
 (0)