perf: replace DispatchQueue.sync with NSLock in RegexManager to prevent UI freezes - #893
Conversation
PR Review SummaryOverall AssessmentThe motivation is sound and well-documented — Given the project's iOS 12+ deployment target, Critical: Missing
|
| Issue | Severity | Action |
|---|---|---|
Missing defer { unlock() } — deadlock risk |
Critical | Must fix before merge |
| TOCTOU race on concurrent cache miss | Low | Pre-existing, fixed for free with single lock region |
| Stray blank line | Trivial | Clean up |
The performance improvement is valid and welcome. Just needs the defer guard to maintain the same safety level as the original code. Thanks for the contribution!
Thanks for the detailed review and the great catch with defer! I've pushed the requested changes. |
Description
This PR optimizes the thread synchronization mechanism in
RegexManagerby replacing the serialDispatchQueuewith anNSLockto manage access to theregularExpressionPooldictionary.Motivation and Context
Currently,
RegexManageruses a serial queue (regularExpressionPoolQueue.sync) to protect the regex cache from data races. However, there is no explicit documentation warning consumers against calling methods likephoneDataDetectorMatchorregexWithPatternconcurrently from multiple threads. As a result, consumers naturally use the library across various concurrent queues.When accessed heavily in a multi-threaded environment, the
DispatchQueue.syncapproach becomes a significant bottleneck. The overhead of GCD context switching, queue management, and potential priority inversion makes it an uneconomical choice for simple, high-frequency dictionary read/write operations.Switching to
NSLockprovides a much lower-level, lightweight locking mechanism. It guarantees the necessary thread safety (preventingEXC_BAD_ACCESSduring concurrent dictionary mutations) while drastically reducing overhead, lock contention time, and improving overall throughput for concurrent callers.How Has This Been Tested?
Types of changes