gpt4 book ai didi

c# - 为什么我的 StringReader 比 .NET StringReader 慢 50us?

转载 作者:行者123 更新时间:2023-11-30 13:16:16 26 4
gpt4 key购买 nike

在我的测试中,我创建了一个包含 32000 个字符的字符串。重复执行测试后,BCL StringReader 始终在 350us 内执行,而我的则在 400us 内运行。他们隐藏着什么样的 secret ?

测试:

private void SpeedTest()
{
String r = "";
for (int i = 0; i < 1000; i++)
{
r += Randomization.GenerateString();
}

StopWatch s = new StopWatch();
s.Start();
using (var sr = new System.IO.StringReader(r))
{
while (sr.Peek() > -1)
{
sr.Read();
}
}

s.Stop();
_Write(s.Elapsed);
s.Reset();
s.Start();

using (var sr = new MagicSynthesis.StringReader(r))
{
while (sr.PeekNext() > Char.MinValue)
{
sr.Next();
}
}

s.Stop();
_Write(s.Elapsed);
}

代码:

public unsafe class StringReader : IDisposable
{
private Char* Base;
private Char* End;
private Char* Current;
private const Char Null = '\0';


/// <summary></summary>
public StringReader(String s)
{
if (s == null)
throw new ArgumentNullException("s");

Base = (Char*)Marshal.StringToHGlobalUni(s).ToPointer();
End = (Base + s.Length);
Current = Base;
}


/// <summary></summary>
public Char Next()
{
return (Current < End) ? *(Current++) : Null;
}

/// <summary></summary>
public String Next(Int32 length)
{
String s = String.Empty;

while (Current < End && length > 0)
{
length--;
s += *(Current++);
}

return s;
}

/// <summary></summary>
public Char PeekNext()
{
return *(Current);
}

/// <summary></summary>
public String PeekNext(Int32 length)
{
String s = String.Empty;
Char* a = Current;

while (Current < End && length > 0)
{
length--;
s += *(Current++);
}

Current = a;

return s;
}


/// <summary></summary>
public Char Previous()
{
return ((Current > Base) ? *(--Current) : Null);
}

/// <summary></summary>
public Char PeekPrevious()
{
return ((Current > Base) ? *(Current - 1) : Null);
}


/// <summary></summary>
public void Dispose()
{
Marshal.FreeHGlobal(new IntPtr(Base));
}
}

最佳答案

我敢打赌,Marshal.StringToHGlobalUni()Marshal.FreeHGlobal(new IntPtr(Base)) 与差异有很大关系。我不确定 StringReader 如何管理字符串,但我敢打赌它不会将其复制到非托管内存。

查看 Reflector 中的 StringReader.Read() 方法表明:

public override int Read()
{
if (this._s == null)
{
__Error.ReaderClosed();
}
if (this._pos == this._length)
{
return -1;
}
return this._s[this._pos++];
}

构造函数也只是:

public StringReader(string s)
{
if (s == null)
{
throw new ArgumentNullException("s");
}
this._s = s;
this._length = (s == null) ? 0 : s.Length;
}

因此,StringReader 似乎只是保持当前位置并使用常规索引返回值。

编辑
为了回应您的评论,您的 Next() 方法进行了比较和不安全的强制转换,这可能没有以任何方式进行优化。 StringReader.Read() 做简单的比较,将字符作为字符串中的_pos 索引返回,这可能是编译器做了一些优化。

关于c# - 为什么我的 StringReader 比 .NET StringReader 慢 50us?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1403146/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com