Open jhughes2112 opened 3 years ago
Since I'm giving you code, here's an updated version of WriteString() that is table driven and significantly faster than what's there. I was profiling today and this was coming up a lot for long documents. It removes the vast majority of the comparisons using a simple lookup table.
In my version, I also removed all the ToLowerInvariant() support, because that creates a lot of allocations whether you enable the write-as-lower feature or not.
Enjoy!
static private bool[] escapedUnicodeSet = null;
static private bool[] normalSet = null;
private void WriteString(string s)
{
// Build lookup tables
if (escapedUnicodeSet==null)
{
escapedUnicodeSet = new bool[256];
normalSet = new bool[256];
for (int c=0; c<256; c++)
{
escapedUnicodeSet[c] = (c >= ' ' && c < 128 && c != '\"' && c != '\\');
normalSet[c] = (c != '\t' && c != '\n' && c != '\r' && c != '\"' && c != '\\' && c != '\0'); // && c != ':' && c!=',')
}
}
_output.Append('\"');
bool[] setToUse = _useEscapedUnicode ? escapedUnicodeSet : normalSet; // table-driven removes almost all the comparisons
int runIndex = -1;
int l = s.Length;
for (var index = 0; index < l; ++index)
{
var c = s[index];
if (setToUse[c])
{
if (runIndex == -1)
runIndex = index;
continue;
}
if (runIndex != -1)
{
_output.Append(s, runIndex, index - runIndex);
runIndex = -1;
}
switch (c)
{
case '\t': _output.Append('\\').Append('t'); break;
case '\r': _output.Append('\\').Append('r'); break;
case '\n': _output.Append('\\').Append('n'); break;
case '"':
case '\\': _output.Append('\\'); _output.Append(c); break;
case '\0': _output.Append("\\u0000"); break;
default:
if (_useEscapedUnicode)
{
_output.Append("\\u");
_output.Append(((int)c).ToString("X4", NumberFormatInfo.InvariantInfo));
}
else
_output.Append(c);
break;
}
}
if (runIndex != -1)
_output.Append(s, runIndex, s.Length - runIndex);
_output.Append('\"');
}
Thanks! I will check and let you know.
Here's the error (which was reported previously, but nobody actually solved):
Here is some simple test code that shows it broken:
Basically what is happening is the Reflection.CreateGetMethod() was doing the wrong thing for static getters in structs. Here's how I modified it to work, which does deserialize properly: