ecac49f9f0
The SHA256 pool used ArrayBlockingQueue.take()/put() which acquire a lock on every call. Profiling showed ~10µs synchronization overhead per SHA256 for ~2µs of actual hashing — the lock cost 5× more than the hash itself. Replaced with ThreadLocal<MessageDigest> which gives each thread its own instance with zero synchronization. MessageDigest.digest() implicitly resets state, so no explicit reset is needed. The pool is kept available for streaming use cases (hashStream) that need incremental hashing with update()/digest() across multiple calls. Only affects jvmAndroid — Apple uses CC_SHA256 directly, Linux uses whyoleg CryptographyProvider. Both already have no pool overhead. https://claude.ai/code/session_01BhU63WUe9AhikZxRdw3Lpg