Three sibling enums all perform their wire-string lookup with the same pattern: Arrays.stream(values()).filter(t -> t.wire.equals(s)).findFirst(). The sites are arcp-core/src/main/java/dev/arcp/core/messages/Message.java lines 57-62, arcp-core/src/main/java/dev/arcp/core/events/EventBody.java lines 44-49, and arcp-core/src/main/java/dev/arcp/core/capabilities/Feature.java lines 33-35. Every call allocates a Stream pipeline (with at least three intermediate objects: the Spliterator over values(), the Stream itself, and the lambda capture) plus an Optional, then walks the enum linearly. Both Messages.decode and Events.decode call into these lookups for every inbound envelope and every job event — that is the runtime's primary dispatch hot path, in some deployments running at thousands of envelopes per second per session.\n\nFix prompt: In each of the three enums (Message.Type, EventBody.Kind, Feature) replace the stream-based lookup with a static immutable Map<String, Type> BY_WIRE (or BY_WIRE per enum) initialized in a static initializer block. Use Map.copyOf(Arrays.stream(values()).collect(Collectors.toMap(Type::wire, Function.identity()))) so the map is immutable, or build it manually into a HashMap and wrap in Collections.unmodifiableMap. Rewrite fromWire to call BY_WIRE.get(wire) and either throw IllegalArgumentException (Message.Type, EventBody.Kind) or return Optional.ofNullable (Feature) to preserve the existing return types. This drops the per-call allocation to zero and the lookup from O(n) to O(1). Verify with an existing round-trip test (e.g. arcp-core EnvelopeRoundTripTest) that decoding behavior is unchanged.
Three sibling enums all perform their wire-string lookup with the same pattern:
Arrays.stream(values()).filter(t -> t.wire.equals(s)).findFirst(). The sites are arcp-core/src/main/java/dev/arcp/core/messages/Message.java lines 57-62, arcp-core/src/main/java/dev/arcp/core/events/EventBody.java lines 44-49, and arcp-core/src/main/java/dev/arcp/core/capabilities/Feature.java lines 33-35. Every call allocates a Stream pipeline (with at least three intermediate objects: the Spliterator over values(), the Stream itself, and the lambda capture) plus an Optional, then walks the enum linearly. Both Messages.decode and Events.decode call into these lookups for every inbound envelope and every job event — that is the runtime's primary dispatch hot path, in some deployments running at thousands of envelopes per second per session.\n\nFix prompt: In each of the three enums (Message.Type, EventBody.Kind, Feature) replace the stream-based lookup with a static immutableMap<String, Type> BY_WIRE(or BY_WIRE per enum) initialized in a static initializer block. UseMap.copyOf(Arrays.stream(values()).collect(Collectors.toMap(Type::wire, Function.identity())))so the map is immutable, or build it manually into a HashMap and wrap inCollections.unmodifiableMap. Rewrite fromWire to callBY_WIRE.get(wire)and either throw IllegalArgumentException (Message.Type, EventBody.Kind) or return Optional.ofNullable (Feature) to preserve the existing return types. This drops the per-call allocation to zero and the lookup from O(n) to O(1). Verify with an existing round-trip test (e.g. arcp-core EnvelopeRoundTripTest) that decoding behavior is unchanged.