Improving the performance degradation caused by Span generation

This commit is contained in:
hadashiA
2026-07-30 13:25:13 +09:00
parent 6d011f737e
commit f653f10750
4 changed files with 41 additions and 78 deletions

View File

@@ -66,14 +66,16 @@ namespace UniJSON
/// <returns></returns>
static JsonNode ParsePrimitive(JsonNode tree, Utf8String segment, ValueNodeType valueType)
{
var span = segment.Bytes.Span;
int i = 1;
for (; i < segment.ByteLength; ++i)
for (; i < span.Length; ++i)
{
if (Char.IsWhiteSpace((char)segment[i])
|| segment[i] == '}'
|| segment[i] == ']'
|| segment[i] == ','
|| segment[i] == ':'
var b = span[i];
if (Char.IsWhiteSpace((char)b)
|| b == '}'
|| b == ']'
|| b == ','
|| b == ':'
)
{
break;

View File

@@ -1,19 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace UniJSON
{
public struct Utf8Iterator : IEnumerator<Byte>
public ref struct Utf8Iterator
{
ReadOnlyMemory<byte> m_memory;
ReadOnlySpan<byte> m_span;
int m_start;
int m_position;
public Utf8Iterator(ReadOnlyMemory<Byte> memory, int start = 0)
: this(memory.Span, start)
{
m_memory = memory;
}
public Utf8Iterator(ReadOnlySpan<Byte> span, int start = 0)
{
m_span = span;
m_start = start;
m_position = -1;
}
@@ -53,27 +56,22 @@ namespace UniJSON
public byte Current
{
get { return m_memory.Span[m_position]; }
}
object IEnumerator.Current
{
get { return Current; }
get { return m_span[m_position]; }
}
public byte Second
{
get { return m_memory.Span[m_position + 1]; }
get { return m_span[m_position + 1]; }
}
public byte Third
{
get { return m_memory.Span[m_position + 2]; }
get { return m_span[m_position + 2]; }
}
public byte Fourth
{
get { return m_memory.Span[m_position + 3]; }
get { return m_span[m_position + 3]; }
}
public const uint Mask1 = 0x01;
@@ -170,10 +168,6 @@ namespace UniJSON
}
}
public void Dispose()
{
}
public bool MoveNext()
{
if (m_position == -1)
@@ -184,7 +178,7 @@ namespace UniJSON
{
m_position += CurrentByteLength;
}
return m_position < m_memory.Length;
return m_position < m_span.Length;
}
public void Reset()

View File

@@ -139,38 +139,12 @@ namespace UniJSON
public bool StartsWith(Utf8String rhs)
{
if (rhs.ByteLength > ByteLength)
{
return false;
}
for (int i = 0; i < rhs.ByteLength; ++i)
{
if (this[i] != rhs[i])
{
return false;
}
}
return true;
return Bytes.Span.StartsWith(rhs.Bytes.Span);
}
public bool EndsWith(Utf8String rhs)
{
if (rhs.ByteLength > ByteLength)
{
return false;
}
for (int i = 1; i <= rhs.ByteLength; ++i)
{
if (this[ByteLength - i] != rhs[rhs.ByteLength - i])
{
return false;
}
}
return true;
return Bytes.Span.EndsWith(rhs.Bytes.Span);
}
public int IndexOf(Byte code)
@@ -219,10 +193,11 @@ namespace UniJSON
public Utf8String TrimStart()
{
var span = Bytes.Span;
var i = 0;
for (; i < ByteLength; ++i)
for (; i < span.Length; ++i)
{
if (!IsSpace(this[i]))
if (!IsSpace(span[i]))
{
break;
}
@@ -232,10 +207,11 @@ namespace UniJSON
public Utf8String TrimEnd()
{
var i = ByteLength-1;
var span = Bytes.Span;
var i = span.Length - 1;
for (; i >= 0; --i)
{
if (!IsSpace(this[i]))
if (!IsSpace(span[i]))
{
break;
}
@@ -265,20 +241,7 @@ namespace UniJSON
public bool Equals(Utf8String other)
{
if (ByteLength != other.ByteLength)
{
return false;
}
for (int i = 0; i < ByteLength; ++i)
{
if (this[i] != other[i])
{
return false;
}
}
return true;
return Bytes.Span.SequenceEqual(other.Bytes.Span);
}
public override int GetHashCode()
@@ -296,9 +259,10 @@ namespace UniJSON
get
{
//bool isInt = false;
for (int i = 0; i < ByteLength; ++i)
var span = Bytes.Span;
for (int i = 0; i < span.Length; ++i)
{
var c = this[i];
var c = span[i];
if (c == '0'
|| c == '1'
|| c == '2'

View File

@@ -23,10 +23,11 @@ namespace UniJSON
public static bool TrySearchByte(this Utf8String src, Func<byte, bool> pred, out int pos)
{
var span = src.Bytes.Span;
pos = 0;
for (; pos < src.ByteLength; ++pos)
for (; pos < span.Length; ++pos)
{
if (pred(src[pos]))
if (pred(span[pos]))
{
return true;
}
@@ -88,6 +89,7 @@ namespace UniJSON
public static IEnumerable<Utf8String> Split(this Utf8String src, byte delimiter)
{
var results = new List<Utf8String>();
var start = 0;
var p = new Utf8Iterator(src.Bytes);
while (p.MoveNext())
@@ -96,11 +98,11 @@ namespace UniJSON
{
if (p.BytePosition - start == 0)
{
yield return default(Utf8String);
results.Add(default(Utf8String));
}
else
{
yield return src.Subbytes(start, p.BytePosition - start);
results.Add(src.Subbytes(start, p.BytePosition - start));
}
start = p.BytePosition + 1;
}
@@ -108,8 +110,9 @@ namespace UniJSON
if (start < p.BytePosition)
{
yield return src.Subbytes(start, p.BytePosition - start);
results.Add(src.Subbytes(start, p.BytePosition - start));
}
return results;
}
#region atoi