String.Where性能相对较差的地方 [英] String.Where Comparatively Poor Performance

查看:89
本文介绍了String.Where性能相对较差的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个方法,它们采用字符串并删除所有无效"字符(哈希集中包含的字符).一种方法使用Linq;另一种方法使用带w/char数组的循环.

Linq方法(208756.9滴答)花费的时间几乎是循环(108688.2滴答)的两倍

Linq:

    string Linq(string field)
    {
        var c = field.Where(p => !hashChar.Contains(p));
        return new string(c.ToArray());
    }

循环:

    string CharArray(string field)
    {
        char[] c = new char[field.Length];
        int count = 0;

        for (int i = 0; i < field.Length; i++)
            if (!hashChar.Contains(field[i]))
            {
                c[count] = field[i];
                count++;
            }

        if (count == 0)
            return field;

        char[] f = new char[count];

        Buffer.BlockCopy(c, 0, f, 0, count * sizeof(char));

        return new string(f);
    }

我的期望是LINQ会胜过或至少与Loop方法相当.循环方法甚至没有优化.我一定在这里想念什么.

Linq.如何在后台运行,为什么它不适合我的方法?

解决方案

如果 解决方案

If the source code of ToArray in Mono is any indication, your implementation wins because it performs fewer allocations (scroll down to line 2874 to see the method).

Like many methods of LINQ, the ToArray method contains separate code paths for collections and for other enumerables:

TSource[] array;
var collection = source as ICollection<TSource>;
if (collection != null) {
    ...
    return array;
}

In your case, this branch is not taken, so the code proceeds to this loop:

int pos = 0;
array = EmptyOf<TSource>.Instance;
foreach (var element in source) {
    if (pos == array.Length) {
        if (pos == 0)
            array = new TSource [4];
        else
            // If the number of returned character is significant,
            // this method will be called multiple times
            Array.Resize (ref array, pos * 2);
    }
    array[pos++] = element;
}

if (pos != array.Length)
    Array.Resize (ref array, pos);

return array;

As you can see, LINQ's version may allocate and re-allocate the array several times. Your implementation, on the other hand, does just two allocations - the upfront one of the max size, and the final one, where the data is copied. That's why your code is faster.

这篇关于String.Where性能相对较差的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆