类型转换性能可优化?
type conversion performance optimizable?
以下代码片段在数据处理应用程序中将 xml 数据转换为 csv 数据。 element
是一个 XElement
。我目前正在尝试优化应用程序的性能,并且想知道我是否可以以某种方式组合下面进行的两个操作:最终我仍然希望访问 joined 的字符串值和列表中的值的元素,因为它们被使用以后用于其他目的。不确定这是否可行。任何帮助将不胜感激!
第一个操作基本上去除所有标签的 XML 数据,只去除标签之间或标签之外的文本数据 returns。它还检查格式。第二个操作获取 XML 数据并删除所有换行符和空格(如果它们存在于数据的前几个字符中)。
IEnumerable<string> values = new List<string>();
values = element.DescendantNodes().OfType<XText>()
.Select(v => Regex.Replace(v.Value, "\s+", " ")).ToList();
string joined = string.Concat(element.ToString().Split().Take(3)) + string.Join(" ", element.
ToString().Split().Skip(3));
IEnumerable<string> values = new List<string>();
values = …
可能不会有什么大不了的,但为什么创建一个新的 List<string>()
只是为了扔掉它。将其替换为:
IEnumerable<string> values;
values = …
如果您需要 values
在之前的作用域中定义,否则只需:
Enumerable<string> values = …
然后:
….Select(v => Regex.Replace(v.Value, "\s+", " ")).ToList();
你真的需要它成为一个列表吗?与just比较速度:
….Select(v => Regex.Replace(v.Value, "\s+", " "));
有时速度会变慢,有时根本行不通,但很多时候 ToList()
只是浪费时间和内存。
string joined = string.Concat(
element.ToString().Split().Take(3))
+ string.Join(" ", element.ToString().Split().Skip(3));
首先你为什么要调用 ToString()
和 Split()
两次?:
var splitOnWhiteSpace = element.ToString().Split();
string joined = string.Concat(
splitOnWhiteSpace.Take(3))
+ string.Join(" ", splitOnWhiteSpace.Skip(3));
我们也可以使用自定义方法优化 Join
:
var elString = element.ToString();
var buffer = new StringBuilder(element.Length - 2); //Can't be larger, unlikely to be much smaller so obtain necessary space in advance.
using(var en = elString.Split().GetEnumerator())
{
int count = 0;
while(en.MoveNext() && ++count != 4)
buffer.Append(en.Current);
while(en.MoveNext())
buffer.Append(en.Current).Append(' ');
}
string joined = buffer.ToString();
如果这被多个循环击中,我会考虑在循环之间保留缓冲区(Clear()
它在每次使用后而不是创建一个新的)。
如果要拆分的字符串非常大,我可能会考虑 Split()
的自定义版本,它遍历字符串,只发出它需要的块,而不是在每次传递时都创建一个数组,但我不会担心这一点,直到我首先尝试了上述更明显的改进。
以下代码片段在数据处理应用程序中将 xml 数据转换为 csv 数据。 element
是一个 XElement
。我目前正在尝试优化应用程序的性能,并且想知道我是否可以以某种方式组合下面进行的两个操作:最终我仍然希望访问 joined 的字符串值和列表中的值的元素,因为它们被使用以后用于其他目的。不确定这是否可行。任何帮助将不胜感激!
第一个操作基本上去除所有标签的 XML 数据,只去除标签之间或标签之外的文本数据 returns。它还检查格式。第二个操作获取 XML 数据并删除所有换行符和空格(如果它们存在于数据的前几个字符中)。
IEnumerable<string> values = new List<string>();
values = element.DescendantNodes().OfType<XText>()
.Select(v => Regex.Replace(v.Value, "\s+", " ")).ToList();
string joined = string.Concat(element.ToString().Split().Take(3)) + string.Join(" ", element.
ToString().Split().Skip(3));
IEnumerable<string> values = new List<string>();
values = …
可能不会有什么大不了的,但为什么创建一个新的 List<string>()
只是为了扔掉它。将其替换为:
IEnumerable<string> values;
values = …
如果您需要 values
在之前的作用域中定义,否则只需:
Enumerable<string> values = …
然后:
….Select(v => Regex.Replace(v.Value, "\s+", " ")).ToList();
你真的需要它成为一个列表吗?与just比较速度:
….Select(v => Regex.Replace(v.Value, "\s+", " "));
有时速度会变慢,有时根本行不通,但很多时候 ToList()
只是浪费时间和内存。
string joined = string.Concat(
element.ToString().Split().Take(3))
+ string.Join(" ", element.ToString().Split().Skip(3));
首先你为什么要调用 ToString()
和 Split()
两次?:
var splitOnWhiteSpace = element.ToString().Split();
string joined = string.Concat(
splitOnWhiteSpace.Take(3))
+ string.Join(" ", splitOnWhiteSpace.Skip(3));
我们也可以使用自定义方法优化 Join
:
var elString = element.ToString();
var buffer = new StringBuilder(element.Length - 2); //Can't be larger, unlikely to be much smaller so obtain necessary space in advance.
using(var en = elString.Split().GetEnumerator())
{
int count = 0;
while(en.MoveNext() && ++count != 4)
buffer.Append(en.Current);
while(en.MoveNext())
buffer.Append(en.Current).Append(' ');
}
string joined = buffer.ToString();
如果这被多个循环击中,我会考虑在循环之间保留缓冲区(Clear()
它在每次使用后而不是创建一个新的)。
如果要拆分的字符串非常大,我可能会考虑 Split()
的自定义版本,它遍历字符串,只发出它需要的块,而不是在每次传递时都创建一个数组,但我不会担心这一点,直到我首先尝试了上述更明显的改进。