I'm trying to encode a KeyValuePair<string, string>
to UTF-8 key='value'
using the Span<byte>
overloads in .NET Core 2.1.
Whoever wrote the GetBytes(ReadOnlySpan<char> chars, Span<byte> bytes)
method was obviously a disciple of Yoda, because there is no TryGetBytes
alternative, which is odd since Utf8Formatter provides TryWrite for all non-string primitive types.
So I have two options for writing an extension method to do this.
Option 1:
public static bool TryGetBytes(this Encoding encoding, ReadOnlySpan<char> str, Span<byte> bytes, out int written)
{
try
{
written = Encoding.UTF8.GetBytes(str, span);
return true;
}
catch (ArgumentException)
{
written = 0;
return false;
}
Option 2:
public static bool TryGetBytes(this Encoding encoding, ReadOnlySpan<char> str, Span<byte> bytes, out int written)
{
if (encoding.GetByteCount(str) > span.Length)
{
written = 0;
return false;
}
written = Encoding.UTF8.GetBytes(str, span);
return true;
}
Which is better for performance, assuming that the "not enough space" case will be hit fairly frequently (say, 1 time in 50) on a hot path?
As I was writing this question, I thought "why don't you just BenchmarkDotNet it?" so I did.
Answer: GetByteCount
is two orders of magnitude faster than try/catch
.
Here are the results:
BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17763.253 (1809/October2018Update/Redstone5)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.2.102
[Host] : .NET Core 2.2.1 (CoreCLR 4.6.27207.03, CoreFX 4.6.27207.03), 64bit RyuJIT
DefaultJob : .NET Core 2.2.1 (CoreCLR 4.6.27207.03, CoreFX 4.6.27207.03), 64bit RyuJIT
| Method | Mean | Error | StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
|--------- |------------:|-----------:|----------:|------------:|------------:|------------:|--------------------:|
| TryCatch | 40,985.9 ns | 800.034 ns | 785.74 ns | 0.4272 | - | - | 1392 B |
| TryCount | 366.5 ns | 8.450 ns | 10.38 ns | - | - | - | - |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With