代码在Xamarin上运行慢了很多.Android应用程序与主机应用程序的比较
本文关键字:应用程序 Android 主机 比较 Xamarin 运行 代码 | 更新日期: 2023-09-27 18:04:51
我在一个PCL项目中为String
编写了一个扩展方法:
public static ICollection<string[]> SplitAt(this string input, char target, int length, StringSplitOptions opts, bool trin = false()
{
string[] itens = input.Split(new char[] { target }, opts);
return InternalSplitAt(itens, target, length, trim);
}
private static ICollection<string[]> InternalSplitAt(string[] itens, char target, int length, bool trim = false)
{
var collectionToReturn = new List<string[]>();
var targetString = target.ToString();
do
{
string firstPart = string.Join(targetString, itens.Take(length));
collectionToReturn.Add(firstPart.Split(target));
if (trim)
{
itens = itens.Skip(length).Select(x => x.Trim()).ToArray();
}
else
{
itens = itens.Skip(length).ToArray();
}
}
while (itens.Length >= length);
return collectionToReturn;
}
然后我像这样使用SplitAt
方法:
var arr = str.SplitAt('#', 34, StringSplitOption.None);
str
是一个有280474个字符的String
。
当我在Xamarin中调用上述代码时。Android应用程序几乎需要40秒才能完成,而在控制台应用程序中,只需1秒。
我的代码可以在任何改进,使其在Android上运行得更快?
注意:该扩展方法是基于一段时间前我从另一个StackOverflow问题中得到的代码,我认为,但我找不到它再次给予适当的信任。
编辑:解释我想要完成的事情:我有一个这样的字符串:
var str = "001#Test#002#Test#003#Test";
通过#执行正常的Split
,我会得到一个数组this:
string[] { "001", "Test", "002", "Test", "003", "Test" }
但是我需要它是三个不同的数组,所以像这样调用扩展名:
var arr = str.SplitAt('#', 2, StringSplitOption.None);
我:string[] { "001", "Test" }
string[] { "002", "Test" }
string[] { "003", "Test" }
在我的实际场景中,280474字符串具有53074个#字符,并且由于我使用34作为长度参数调用扩展名,因此我的最终输出将是一个包含1561个条目(53074/34)的iccollection,每个条目都是string[34]
。
试试这个,我已经减少了完成任务所需的操作数量。此外,我已经完成了最初的修剪,以防您需要它,所以代码不会多次调用修剪。它在我的机器上运行速度快了6倍,大约有10k的测试数据。
public static ICollection<string[]> SplitAt(this string input, char target, int length, StringSplitOptions opts, bool trim = false)
{
var items = input.Split(new[] { target }, opts);
if (trim) items = items.Select(x => x.Trim()).ToArray();
return InternalSplitAt(items, length);
}
private static ICollection<string[]> InternalSplitAt(string[] items, int length)
{
var collectionToReturn = new List<string[]>();
for (int i = 0; i < items.Length; i += length)
{
collectionToReturn.Add(items.Skip(i).Take(length).ToArray());
}
return collectionToReturn;
}
基于@Simon的回答和@Jon Skeet的评论,我想出了一个非常有效的解决方案,在20~30毫秒内运行。在这种情况下,使用ToArray
和字符串连接创建数组确实会影响性能。
public static ICollection<string[]> SplitAt(this string input, char target, int length, StringSplitOptions, opts = StringSplitOptions.None, bool trim = false)
{
string[] itens = input.Split(new char[] { target }, opts);
if (trim) itens = itens.Select(s => s.Trim()).ToArray();
return InternalSplitAt(itens, length);
}
private static ICollection<string[]> InternalSplitAt(string[] itens, char target, int length, bool trim = false)
{
var collectionToReturn = new List<string[]>();
var loops = itens.Length / length;
for (int i = 0; i < loops; i++)
{
var arrayToAdd = new string[length];
Array.Copy(itens, i * length, newArray, 0, length);
ret.Add(arrayToAdd);
}
return collectionToReturn;
}
感谢这一节的答案,我取了数组的一部分。
再次感谢Simon提供的有用的答案,感谢Jon Skeet指出了数组创建和字符串连接中可能存在的问题。