3B
Performance optimization pass — caching, data structures, and hot-path improvements across Java and Python.
Changes
Java — Reflection & Caching
- Cache
getMethods()per class inBridgeInstanceandRefFacade— avoids repeated reflection on every reflective invoke - Cache NMS reflection handles (
parseTag,getHandle,spawnNonLivingNmshelpers) inEntitySpawnerstatic fields - Cache LuckPerms API instance and
Node/InheritanceNodeclass objects inPermissionsFacade - Cache resolved event classes across 13 Bukkit packages in
EventSubscription— avoids repeatedClass.forName()for known events - Build static
Map<String, PacketType>lookup tables inPacketBridge— O(1) packet type resolution - Merge dual method+miss cache into single
ConcurrentHashMap<String, Optional<Method>>inEventDispatcherandBridgeSerializer - Cache
getLogicalTypeName()per concrete class inBridgeSerializer— avoids repeated instanceof chains on every serialize
Java — Serialization & I/O
- ThreadLocal
ByteArrayOutputStreamforsend()— avoids allocation per outgoing message - ThreadLocal identity-hash set for cyclic reference detection in
serialize()— reused across calls - New
sendAll()method batches multiple responses under a single lock + flush for batch/frame calls - ItemStack meta: call
displayName()/lore()once with null check instead ofhas*()+get*()pairs - Shallow top-level entry copy instead of
deepCopy()for per-block event payloads inEventDispatcher - Reduce per-pixel overhead in
spawnImagePixels— singleget()+ null check replaceshas()+get()pairs
Java — Data Structures & Dispatch
BridgeInstance.invoke(): else-if dispatch chain replaces sequential instanceof checks — first match winsObjectRegistry:StampedLockreplacessynchronizedblock — lock-free reads viaConcurrentHashMap, write lock only for register/releaseDebugManager:CopyOnWriteArraySetreplacessynchronizedSet— writes are rare (toggle), reads (broadcast) are frequentPlayerUuidResolver: staticHttpClientsingleton, LRU eviction viaLinkedHashMap, cachedusercache.jsonparse with timestampScriptCommand: pre-lowercase tab completions at registration — avoidstoLowerCase()on every keystrokeEventSubscription.lastDispatchNanomarkedvolatilefor safe cross-thread reads- Expanded thread-safe method sets for
Server,OfflinePlayer, andEntity— more calls skip main-thread dispatch - Static empty
JsonObjectsentinel for missingargsininvoke()
Python — Connection & Dispatch
- Lazy module-level imports in
connection.py—_ensure_lazy_imports()populates references once, avoids per-callimport/fromoverhead - Single-handler fast path in
_dispatch_event— when only 1 handler, directly call+await without list/gather overhead _build_call_message()extracted — shared betweencall()andcall_sync(), eliminates duplicated message construction- Release queue changed from
listtoset— O(1)discard()replaces O(n)list.remove() _maybe_flush_releases()avoids unnecessary flushes on every call — only flushes when queue ≥ 16_read_exact()optimistic fast path — singleos.read()often returns full message, skipsbytearrayaccumulationsend()writes header+data in onewrite()call instead of two
Python — Proxy & Types
- Lazy module-level dispatch table for
_proxy_from()— suffix/contains lookup tables built once, avoids per-call dict literal and import - Handle-first fast path in
ProxyBase.__eq__— same handle means same Java object, skip field comparison EnumValue.from_name()dict cache — returns cached instances for repeated enum lookups- Bounded
_player_uuid_cache(max 1000, evict oldest quarter) in bothwrappers.pyandutils.py - Consolidated
isinstancechecks indecorators.pycommand wrapper — merged two separate branches into one
Python — Helpers
State._instancesusesweakref.ref— allows garbage collection of unreferenced State objects- Shutdown handler updated to dereference weakrefs