与控制台应用程序相比,Xamarin.Android应用程序上的代码运行速度慢了很多

时间:2016-08-31 13:03:39

标签: c# performance xamarin xamarin.android

我在 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);

strString,有280474个字符。

当我在Xamarin.Android应用程序中调用上述代码时,需要大约40秒才能完成,在控制台应用程序中需要1秒钟。

我的代码可以改进,以便在Android上运行得更快吗?

注意:这个扩展方法是基于我之前从另一个StackOverflow问题得到的代码,但我再也找不到它给予适当的信任。

修改

解释我想要实现的目标: 我有一个像这样的字符串:

var str = "001#Test#002#Test#003#Test";

通过执行正常的Split,我会得到na数组:

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 作为长度参数调用扩展名,我的最终输出将是一个ICollection,有1561个itens(53074/34),每个都是string[34]

2 个答案:

答案 0 :(得分:1)

试试这个,我减少了完成任务所需的操作次数。此外,我已经完成了最初的修剪以防你需要它,所以代码不会多次调用trim。它在我的机器上运行速度快了大约6倍,测试数据大约为10k。

DataGridTextColumn

答案 1 :(得分:0)

基于 @ 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;
}

对于我参与数组的部分,this answer的积分。

再次感谢Simon提供了有用的答案,感谢Jon Skeet解决了数组创建和字符串连接中可能存在的问题。