perf: optimize MQTT NatsToMqtt fast path and pre-warm topic cache

Add string.Create fast path in NatsToMqtt for subjects without _DOT_
escape sequences (common case), avoiding StringBuilder allocation.
Pre-warm the topic bytes cache when MQTT subscriptions are added to
eliminate cache miss on first message delivery.
This commit is contained in:
Joseph Doherty
2026-03-13 14:44:49 -04:00
parent 7b2def4da1
commit f7a8d72a6d
2 changed files with 15 additions and 1 deletions

View File

@@ -83,6 +83,9 @@ public sealed class MqttNatsClientAdapter : INatsClient
/// </summary>
public Subscription AddSubscription(string natsSubject, string sid, string? queue = null)
{
// Pre-warm topic bytes cache for this subject to avoid cache miss on first message.
MqttTopicMapper.NatsToMqttBytes(natsSubject);
var sub = new Subscription
{
Client = this,

View File

@@ -107,7 +107,18 @@ public static class MqttTopicMapper
if (natsSubject.Length == 0)
return string.Empty;
// First, replace _DOT_ escape sequences back to dots
// Fast path: no _DOT_ escape sequences — just char replacement via string.Create
// (avoids StringBuilder allocation for the common case).
if (!natsSubject.Contains(DotEscape))
{
return string.Create(natsSubject.Length, natsSubject, static (span, src) =>
{
for (var i = 0; i < src.Length; i++)
span[i] = src[i] switch { '.' => '/', '*' => '+', '>' => '#', _ => src[i] };
});
}
// Slow path: has _DOT_ escape sequences — use StringBuilder
var working = natsSubject.Replace(DotEscape, "\x00");
var sb = new StringBuilder(working.Length);