提交 587b1c26 编写于 作者: P Pharring

PERF: TryReadByteOrderMark allocs

Stream.ReadByte() allocates a byte[1] each time. This change uses a thread-local allocation to avoid that allocation. (changeset 1354061)
上级 e0083e5c
......@@ -317,53 +317,52 @@ private static bool TryDecodeMemoryStream(MemoryStream data, Encoding encoding,
return true;
}
private static bool StartsWith(byte[] bytes, byte[] prefix)
[ThreadStatic]
private static byte[] bomBytes;
internal static Encoding TryReadByteOrderMark(Stream data)
{
if (bytes.Length < prefix.Length)
// PERF: Avoid repeated calls to Stream.ReadByte since that method allocates a 1-byte array on each call.
// Instead, using a thread local byte array.
if (bomBytes == null)
{
return false;
bomBytes = new byte[2];
}
for (int i = 0; i < prefix.Length; i++)
{
if (bytes[i] != prefix[i])
{
return false;
}
}
return true;
}
internal static Encoding TryReadByteOrderMark(Stream data)
{
data.Seek(0, SeekOrigin.Begin);
switch (data.ReadByte())
int bytesRead = data.Read(bomBytes, 0, 2);
if (bytesRead == 2)
{
case 0xFE:
if (data.ReadByte() == 0xFF)
{
return Encoding.BigEndianUnicode;
}
break;
case 0xFF:
if (data.ReadByte() == 0xFE)
{
return Encoding.Unicode;
}
break;
case 0xEF:
if (data.ReadByte() == 0xBB && data.ReadByte() == 0xBF)
{
return Encoding.UTF8;
}
break;
switch (bomBytes[0])
{
case 0xFE:
if (bomBytes[1] == 0xFF)
{
return Encoding.BigEndianUnicode;
}
break;
case 0xFF:
if (bomBytes[1] == 0xFE)
{
return Encoding.Unicode;
}
break;
case 0xEF:
if (bomBytes[1] == 0xBB)
{
if (data.Read(bomBytes, 0, 1) == 1 && bomBytes[0] == 0xBF)
{
return Encoding.UTF8;
}
}
break;
}
}
data.Seek(0, SeekOrigin.Begin);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册