【发布时间】:2018-05-31 16:15:54
【问题描述】:
我正在通过 TCP 获取大量数据。数据中有 2 种类型的 XML 数据包。我需要尽快处理它。
<?xml version="1.0" encoding="UTF-8"?><xsi:Event> .... [dynamic length data] .... </xsi:Event>
和
<?xml version="1.0" encoding="UTF-8"?><ChannelHeartBeat xmlns="http://schema.broadsoft.com/xsi"/>
有时数据包没有 xml 声明。
这是旧代码。
char c = (char)streamReader.Read();
sb.Append(c);
if(sb.ToString().EndsWith("</xsi:Event>",StringComparison.OrdinalIgnoreCase))
{
....
sb.Clear();
}
if(sb.ToString().EndsWith("<ChannelHeartBeat xmlns=\"http://schema.broadsoft.com/xsi\"/>", StringComparison.OrdinalIgnoreCase))
{
....
sb.Clear();
}
ToString() 在上述代码中占用了 26% 的 CPU 时间。
以下是优化后的代码。性能提升了 30%
char c = (char)streamReader.Read();
sb.Append(c);
n++;
if (n > 60)
{
if (c == '>')
{
if (n < 105)
{
string temp = sb.ToString();
if (temp.EndsWith("<ChannelHeartBeat xmlns=\"http://schema.broadsoft.com/xsi\"/>", StringComparison.OrdinalIgnoreCase))
{
sb.Clear();
n = 0;
}
}
if (n > 700)
{
string temp = sb.ToString();
if (temp.EndsWith("</xsi:Event>", StringComparison.OrdinalIgnoreCase))
{
sb.Clear();
n = 0;
}
}
}
}
}
ToString() 现在占用了 8% 的 CPU 时间。
我想进一步优化代码。欢迎提出任何建议。
提前致谢。
【问题讨论】:
-
您可以并行化您的代码,以便并行处理 xml。
-
您可以尝试使用
StringBuilder.ToString(int startIndex, int length)函数仅转换字符串的一部分(例如前105个字符或后50个字符)。那么操作应该至少快一点。 -
显示,如何声明和填写
sb -
不要多次调用
sb.ToString(),从块中构造字符串是昂贵的。使用基于数组的缓冲区而不是StringBuilder或List也可能有所帮助(检查性能以确认)。 -
您可以使用循环和索引器 (
sb[i]) 检查字符串生成器是否以某个字符串结尾,完全避免使用ToString
标签: c# string optimization cpu-usage