Skip to content

Commit 5574b17

Browse files
committed
avoid a memcopy by writing directly to the buffer bytes (and increasing DRY)
1 parent e105c6e commit 5574b17

File tree

3 files changed

+11
-21
lines changed

3 files changed

+11
-21
lines changed

src/Middleware/OutputCaching/src/FormatterBinaryWriter.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public void Write(byte value)
7474
DebugAssertValid();
7575
}
7676

77-
public void Write(string value)
77+
public void Write(string value) => Write(value, 0);
78+
79+
internal void Write(string value, int lengthShift)
7880
{
7981
ArgumentNullException.ThrowIfNull(value);
8082

@@ -85,17 +87,19 @@ public void Write(string value)
8587
}
8688

8789
var bytes = Encoding.UTF8.GetByteCount(value);
88-
Write7BitEncodedInt(bytes); // length prefix
90+
Write7BitEncodedInt(bytes << lengthShift); // length prefix
8991
if (bytes <= length - offset)
9092
{
91-
Encoding.UTF8.GetBytes(value, AvailableBuffer);
93+
var actual = Encoding.UTF8.GetBytes(value, AvailableBuffer);
94+
Debug.Assert(actual == bytes);
9295
offset += bytes;
9396
}
9497
else
9598
{
9699
Flush();
97100
// get the encoding to do the heavy lifting directly
98-
Encoding.UTF8.GetBytes(value, target);
101+
var actual = Encoding.UTF8.GetBytes(value, target);
102+
Debug.Assert(actual == bytes);
99103
}
100104
DebugAssertValid();
101105
}

src/Middleware/OutputCaching/src/Microsoft.AspNetCore.OutputCaching.csproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
<IsAspNetCoreApp>true</IsAspNetCoreApp>
77
<IsPackable>false</IsPackable>
88
<IsTrimmable>true</IsTrimmable>
9-
<!-- for skip-locals-init -->
10-
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
119
</PropertyGroup>
1210

1311
<ItemGroup>

src/Middleware/OutputCaching/src/OutputCacheEntryFormatter.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ private static void Serialize(IBufferWriter<byte> output, OutputCacheEntry entry
150150
writer.Flush();
151151
}
152152

153-
[SkipLocalsInit]
154153
static void WriteCommonHeader(ref FormatterBinaryWriter writer, string? value)
155154
{
156155
if (string.IsNullOrEmpty(value))
@@ -165,20 +164,9 @@ static void WriteCommonHeader(ref FormatterBinaryWriter writer, string? value)
165164
}
166165
else
167166
{
168-
var bytes = Encoding.UTF8.GetByteCount(value);
169-
writer.Write7BitEncodedInt(bytes << 1);
170-
171-
const int MAX_STACK_BYTES = 256;
172-
byte[]? leased = null;
173-
174-
Span<byte> buffer = bytes <= MAX_STACK_BYTES ? stackalloc byte[MAX_STACK_BYTES] : (leased = ArrayPool<byte>.Shared.Rent(bytes));
175-
int actual = Encoding.UTF8.GetBytes(value, buffer);
176-
Debug.Assert(actual == bytes);
177-
writer.WriteRaw(buffer.Slice(0, actual));
178-
if (leased is not null)
179-
{
180-
ArrayPool<byte>.Shared.Return(leased);
181-
}
167+
// use the length-prefixed UTF8 write in FormatterBinaryWriter,
168+
// but with a left-shift applied
169+
writer.Write(value, lengthShift: 1);
182170
}
183171
}
184172
}

0 commit comments

Comments
 (0)