gpt4 book ai didi

c# - LINQ 性能影响

转载 作者:行者123 更新时间:2023-11-30 19:52:06 25 4
gpt4 key购买 nike

我有一个简单的程序来去除 XML 中所有非法字符的字符串:

string SanitizeXml(string xml)
{
return string.Concat
(xml.ToCharArray().Where(c => IsLegalXmlChar(c)).ToArray());
}

它简洁明了。但我担心它的性能。使用简单的 for 循环可以轻松完成同样的事情:

string SanitizeXml(string xml)
{
var buffer = new StringBuilder();

foreach(char c in xml)
{
if (IsLegalXmlChar(c))
{
buffer.Append(c);
}
}

return buffer.ToString();
}

让我印象深刻的是,在第二个示例中,xml 被转换为 char[],而 Where() 的 IEnumerable 又转换回 char[]。我似乎经常用 LINQ 来做这件事——在数组和枚举之间切换。

我应该担心这个吗?一般而言,当有一个可能更冗长的明确替代方法时,我会因为依赖 LINQ 扩展方法而受到什么样的性能影响。

也许这个问题太宽泛了。

最佳答案

好吧,您不需要先调用 ToCharArray()开始 - 字符串工具 IEnumerable<char> .但是,我同意 StringBuilder 和循环在这种情况下可能更合适。

我不确定 string.Concat(char[]) 是做什么的,顺便说一句 - 为什么不直接使用接受 char 数组的字符串构造函数?换句话说,经过这些修改:

static string SanitizeXml(string xml)
{
return new string (xml.Where(c => IsLegalXmlChar(c)).ToArray());
}

我仍然更喜欢 StringBuilder 解决方案,但对于常见情况(几乎没有非法字符),可以通过提供适当的起始容量来改进:

string SanitizeXml(string xml)
{
var buffer = new StringBuilder(xml.Length);

foreach(char c in xml)
{
if (IsLegalXmlChar(c))
{
buffer.Append(c);
}
}

return buffer.ToString();
}

我之前没有想到的另一种选择可能是 StringBuilder 上的扩展方法:

// Can't just call it Append as otherwise StringBuilder.Append(object) would
// be used :(
public static StringBuilder AppendSequence(this StringBuilder builder,
IEnumerable<char> sequence)
{
foreach (char c in sequence)
{
builder.Append(c);
}
return builder;
}

然后你可以像这样使用它:

xml = new StringBuilder(xml.Length)
.AppendSequence(xml.Where(IsLegalXmlChar)
.ToString();

(如果需要,您可以为 AppendSequence 设置其他重载以获取 IEnumerable 等。)

编辑:另一种选择可能是避免如此频繁地调用 Append,而是使用 the overload which appends a substring .然后你可以再次为 StringBuilder 构建一个扩展方法,比如(完全未经测试,恐怕 - 我什至没有尝试编译它):

public static StringBuilder AppendWhere(this StringBuilder builder,
string text,
Func<char, bool> predicate)
{
int start = 0;
bool lastResult = false;
for (int i=0; i < text.Length; i++)
{
if (predicate(text[i]))
{
if (!lastResult)
{
start = i;
lastResult = true;
}
}
else
{
if (lastResult)
{
builder.Append(text, start, i-start);
lastResult = false;
}
}
}
if (lastResult)
{
builder.Append(text, start, text.Length-start);
}
return builder;
}

例子的用法:

xml = new StringBuilder(xml.Length).AppendWhere(xml, IsLegalXmlChar)
.ToString();

另一种选择是将其更改为 String 的扩展方法,延迟创建 StringBuilder,如果您以 start=0 结束,则返回原始字符串。

关于c# - LINQ 性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/454891/

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