From 2a1cdd7426a6c176973802cd3fe7ec019452bb7c Mon Sep 17 00:00:00 2001 From: kronic Date: Thu, 18 Nov 2021 14:23:48 +0300 Subject: [PATCH 01/13] Optimize --- .../src/System/Xml/Core/XmlTextEncoder.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index e03320af38639..4f9fd34771966 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -540,13 +540,16 @@ private void WriteStringFragment(string str, int offset, int count, char[] helpe private void WriteCharEntityImpl(char ch) { - WriteCharEntityImpl(((int)ch).ToString("X", NumberFormatInfo.InvariantInfo)); + Span span = stackalloc char[8]; + bool result = ((int)ch).TryFormat(span, out int charsWritten, "X"); + Debug.Assert(result); + WriteCharEntityImpl(span[..charsWritten]); } - private void WriteCharEntityImpl(string strVal) + private void WriteCharEntityImpl(ReadOnlySpan ros) { _textWriter.Write("&#x"); - _textWriter.Write(strVal); + _textWriter.Write(ros); _textWriter.Write(';'); } From 7f95f8d15e7a197fd79e60354e4b824b3cf5f484 Mon Sep 17 00:00:00 2001 From: kronic Date: Thu, 18 Nov 2021 14:32:24 +0300 Subject: [PATCH 02/13] fix NumberFormatInfo.InvariantInfo --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 4f9fd34771966..f5fca3bc44e8a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -541,7 +541,7 @@ private void WriteStringFragment(string str, int offset, int count, char[] helpe private void WriteCharEntityImpl(char ch) { Span span = stackalloc char[8]; - bool result = ((int)ch).TryFormat(span, out int charsWritten, "X"); + bool result = ((int)ch).TryFormat(span, out int charsWritten, "X", NumberFormatInfo.InvariantInfo); Debug.Assert(result); WriteCharEntityImpl(span[..charsWritten]); } From 27945fae702f09e4f870b87db218657c228607c1 Mon Sep 17 00:00:00 2001 From: kronic Date: Fri, 19 Nov 2021 15:23:40 +0300 Subject: [PATCH 03/13] Optimize WriteCharEntity --- .../src/System/Xml/Core/XmlTextEncoder.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index f5fca3bc44e8a..d080bd5137e82 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -488,18 +488,20 @@ internal void WriteCharEntity(char ch) throw new ArgumentException(SR.Xml_InvalidSurrogateMissingLowChar); } - string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); + Span span = stackalloc char[12]; + int charsWritten = CharWriteToSpan(span, ch); + ReadOnlySpan ros = span[..charsWritten]; + if (_cacheAttrValue) { Debug.Assert(_attrValue != null); - _attrValue.Append("&#x"); - _attrValue.Append(strVal); - _attrValue.Append(';'); + _attrValue.Append(ros); } - WriteCharEntityImpl(strVal); + _textWriter.Write(ros); } + internal void WriteEntityRef(string name) { if (_cacheAttrValue) @@ -540,17 +542,21 @@ private void WriteStringFragment(string str, int offset, int count, char[] helpe private void WriteCharEntityImpl(char ch) { - Span span = stackalloc char[8]; - bool result = ((int)ch).TryFormat(span, out int charsWritten, "X", NumberFormatInfo.InvariantInfo); - Debug.Assert(result); - WriteCharEntityImpl(span[..charsWritten]); + Span span = stackalloc char[12]; + int charsWritten = CharWriteToSpan(span, ch); + _textWriter.Write(span[..charsWritten]); } - private void WriteCharEntityImpl(ReadOnlySpan ros) + private static int CharWriteToSpan(Span destination, char ch) { - _textWriter.Write("&#x"); - _textWriter.Write(ros); - _textWriter.Write(';'); + Debug.Assert(destination.Length == 12); + destination[0] = '&'; + destination[1] = '#'; + destination[2] = 'x'; + bool result = ((int)ch).TryFormat(destination[3..], out int charsWritten, "X", NumberFormatInfo.InvariantInfo); + Debug.Assert(result); + destination[charsWritten + 3] = ';'; + return charsWritten + 4; } private void WriteEntityRefImpl(string name) From 3bf4d4c40c148c2bb448c72981563e90ded0c103 Mon Sep 17 00:00:00 2001 From: kronic Date: Fri, 19 Nov 2021 15:25:49 +0300 Subject: [PATCH 04/13] remove empty lines --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index d080bd5137e82..76cbb6c3c6485 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -479,8 +479,6 @@ internal void WriteRaw(char[] array, int offset, int count) _textWriter.Write(array, offset, count); } - - internal void WriteCharEntity(char ch) { if (XmlCharType.IsSurrogate(ch)) @@ -501,7 +499,6 @@ internal void WriteCharEntity(char ch) _textWriter.Write(ros); } - internal void WriteEntityRef(string name) { if (_cacheAttrValue) From d8c0e2891bcb307ecfe58d2113a8d596c3b3cd07 Mon Sep 17 00:00:00 2001 From: kronic Date: Fri, 19 Nov 2021 15:27:12 +0300 Subject: [PATCH 05/13] fix Debug.Assert --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 76cbb6c3c6485..af552f0ff7e6f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -546,7 +546,7 @@ private void WriteCharEntityImpl(char ch) private static int CharWriteToSpan(Span destination, char ch) { - Debug.Assert(destination.Length == 12); + Debug.Assert(destination.Length >= 12); destination[0] = '&'; destination[1] = '#'; destination[2] = 'x'; From aeac4efd4632790d46b2026efeab40f33ff0a6f5 Mon Sep 17 00:00:00 2001 From: kronic Date: Fri, 19 Nov 2021 15:44:09 +0300 Subject: [PATCH 06/13] rename method --- .../src/System/Xml/Core/XmlTextEncoder.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index af552f0ff7e6f..fa8892a883f85 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -487,7 +487,7 @@ internal void WriteCharEntity(char ch) } Span span = stackalloc char[12]; - int charsWritten = CharWriteToSpan(span, ch); + int charsWritten = WriteCharToSpan(span, ch); ReadOnlySpan ros = span[..charsWritten]; if (_cacheAttrValue) @@ -540,11 +540,11 @@ private void WriteStringFragment(string str, int offset, int count, char[] helpe private void WriteCharEntityImpl(char ch) { Span span = stackalloc char[12]; - int charsWritten = CharWriteToSpan(span, ch); + int charsWritten = WriteCharToSpan(span, ch); _textWriter.Write(span[..charsWritten]); } - private static int CharWriteToSpan(Span destination, char ch) + private static int WriteCharToSpan(Span destination, char ch) { Debug.Assert(destination.Length >= 12); destination[0] = '&'; From 1d08024ac3985c5fbc2f335329760324b38c71db Mon Sep 17 00:00:00 2001 From: kronic Date: Fri, 19 Nov 2021 15:50:19 +0300 Subject: [PATCH 07/13] Remove string allocation WriteSurrogateCharEntity --- .../src/System/Xml/Core/XmlTextEncoder.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index fa8892a883f85..26420765d950f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -231,11 +231,11 @@ internal void Write(char[] array, int offset, int count) internal void WriteSurrogateCharEntity(char lowChar, char highChar) { - if (!XmlCharType.IsLowSurrogate(lowChar) || - !XmlCharType.IsHighSurrogate(highChar)) + if (!XmlCharType.IsLowSurrogate(lowChar) || !XmlCharType.IsHighSurrogate(highChar)) { throw XmlConvert.CreateInvalidSurrogatePairException(lowChar, highChar); } + int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); if (_cacheAttrValue) @@ -245,9 +245,9 @@ internal void WriteSurrogateCharEntity(char lowChar, char highChar) _attrValue.Append(lowChar); } - _textWriter.Write("&#x"); - _textWriter.Write(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)); - _textWriter.Write(';'); + Span span = stackalloc char[12]; + int charsWritten = WriteCharToSpan(span, surrogateChar); + _textWriter.Write(span[..charsWritten]); } internal void Write(string text) @@ -544,13 +544,13 @@ private void WriteCharEntityImpl(char ch) _textWriter.Write(span[..charsWritten]); } - private static int WriteCharToSpan(Span destination, char ch) + private static int WriteCharToSpan(Span destination, int ch) { Debug.Assert(destination.Length >= 12); destination[0] = '&'; destination[1] = '#'; destination[2] = 'x'; - bool result = ((int)ch).TryFormat(destination[3..], out int charsWritten, "X", NumberFormatInfo.InvariantInfo); + bool result = ch.TryFormat(destination[3..], out int charsWritten, "X", NumberFormatInfo.InvariantInfo); Debug.Assert(result); destination[charsWritten + 3] = ';'; return charsWritten + 4; From 2a635bee98ae2bc577e3bd6e1167b2a324c9fdc3 Mon Sep 17 00:00:00 2001 From: kronic Date: Mon, 22 Nov 2021 11:27:49 +0300 Subject: [PATCH 08/13] review feedback --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 26420765d950f..1307000a6d511 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -541,7 +541,10 @@ private void WriteCharEntityImpl(char ch) { Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, ch); - _textWriter.Write(span[..charsWritten]); + for (int i = 0; i < charsWritten; i++) + { + _textWriter.Write(span[i]); + } } private static int WriteCharToSpan(Span destination, int ch) From c6b39e49ddf6d8f068c236128a2c950ef49485f7 Mon Sep 17 00:00:00 2001 From: kronic Date: Mon, 22 Nov 2021 11:28:28 +0300 Subject: [PATCH 09/13] add new line --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 1307000a6d511..184288f8e6ea5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -541,6 +541,7 @@ private void WriteCharEntityImpl(char ch) { Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, ch); + for (int i = 0; i < charsWritten; i++) { _textWriter.Write(span[i]); From 5c5d635b5fe3d476d529b7d101a1c320bbd02492 Mon Sep 17 00:00:00 2001 From: kronic Date: Mon, 22 Nov 2021 14:33:35 +0300 Subject: [PATCH 10/13] Use for --- .../src/System/Xml/Core/XmlTextEncoder.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 184288f8e6ea5..79f1e11e11463 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -247,7 +247,11 @@ internal void WriteSurrogateCharEntity(char lowChar, char highChar) Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, surrogateChar); - _textWriter.Write(span[..charsWritten]); + + for (int i = 0; i < charsWritten; i++) + { + _textWriter.Write(span[i]); + } } internal void Write(string text) @@ -488,15 +492,17 @@ internal void WriteCharEntity(char ch) Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, ch); - ReadOnlySpan ros = span[..charsWritten]; if (_cacheAttrValue) { Debug.Assert(_attrValue != null); - _attrValue.Append(ros); + _attrValue.Append(span[..charsWritten]); } - _textWriter.Write(ros); + for (int i = 0; i < charsWritten; i++) + { + _textWriter.Write(span[i]); + } } internal void WriteEntityRef(string name) From 78929a99e6a39ab2db8aa2b3b59d24160307d85a Mon Sep 17 00:00:00 2001 From: kronic Date: Wed, 24 Nov 2021 13:27:31 +0300 Subject: [PATCH 11/13] review feedback --- .../src/System/Xml/Core/XmlTextEncoder.cs | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 79f1e11e11463..7045e67a0f018 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -247,11 +247,7 @@ internal void WriteSurrogateCharEntity(char lowChar, char highChar) Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, surrogateChar); - - for (int i = 0; i < charsWritten; i++) - { - _textWriter.Write(span[i]); - } + _textWriter.Write(span.Slice(0, charsWritten)); } internal void Write(string text) @@ -492,17 +488,15 @@ internal void WriteCharEntity(char ch) Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, ch); + ReadOnlySpan ros = span.Slice(0, charsWritten); if (_cacheAttrValue) { Debug.Assert(_attrValue != null); - _attrValue.Append(span[..charsWritten]); + _attrValue.Append(ros); } - for (int i = 0; i < charsWritten; i++) - { - _textWriter.Write(span[i]); - } + _textWriter.Write(ros); } internal void WriteEntityRef(string name) @@ -547,23 +541,15 @@ private void WriteCharEntityImpl(char ch) { Span span = stackalloc char[12]; int charsWritten = WriteCharToSpan(span, ch); - - for (int i = 0; i < charsWritten; i++) - { - _textWriter.Write(span[i]); - } + _textWriter.Write(span.Slice(0, charsWritten)); } private static int WriteCharToSpan(Span destination, int ch) { Debug.Assert(destination.Length >= 12); - destination[0] = '&'; - destination[1] = '#'; - destination[2] = 'x'; - bool result = ch.TryFormat(destination[3..], out int charsWritten, "X", NumberFormatInfo.InvariantInfo); + bool result = destination.TryWrite(NumberFormatInfo.InvariantInfo, $"&#x{ch:X};", out int charsWritten); Debug.Assert(result); - destination[charsWritten + 3] = ';'; - return charsWritten + 4; + return charsWritten; } private void WriteEntityRefImpl(string name) From 08cb99d548511f192bcc770f29a92ccb7a814d04 Mon Sep 17 00:00:00 2001 From: kronic Date: Thu, 25 Nov 2021 12:55:31 +0300 Subject: [PATCH 12/13] review feedback --- .../System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 7045e67a0f018..0241d0a7c9238 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -547,7 +547,7 @@ private void WriteCharEntityImpl(char ch) private static int WriteCharToSpan(Span destination, int ch) { Debug.Assert(destination.Length >= 12); - bool result = destination.TryWrite(NumberFormatInfo.InvariantInfo, $"&#x{ch:X};", out int charsWritten); + bool result = destination.TryWrite($"&#x{(uint)ch:X};", out int charsWritten); Debug.Assert(result); return charsWritten; } From 56610d21ad070c8d173d89e33f89d9a67c6dea15 Mon Sep 17 00:00:00 2001 From: kronic Date: Mon, 13 Dec 2021 15:28:47 +0300 Subject: [PATCH 13/13] - --- .../src/System/Xml/Core/XmlTextEncoder.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index faf3d5a8149cd..4d894dfb1e9af 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text; using System.Diagnostics; -using System.Globalization; namespace System.Xml { @@ -525,8 +524,12 @@ private void WriteCharEntityImpl(char ch) private static int WriteCharToSpan(Span destination, int ch) { Debug.Assert(destination.Length >= 12); - bool result = destination.TryWrite($"&#x{(uint)ch:X};", out int charsWritten); - Debug.Assert(result); + destination[0] = '&'; + destination[1] = '#'; + destination[2] = 'x'; + ((uint)ch).TryFormat(destination.Slice(3), out int charsWritten, "X"); + Debug.Assert(charsWritten != 0); + destination[charsWritten + 3] = ';'; return charsWritten; }