Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ在简单操作中的效率_C#_Performance_Linq - Fatal编程技术网

C# LINQ在简单操作中的效率

C# LINQ在简单操作中的效率,c#,performance,linq,C#,Performance,Linq,我最近发现了LINQ,我发现它的使用非常有趣。目前,我有以下功能,我不确定它是否会更有效,毕竟,产生相同的输出 你能告诉我你对此的看法吗 该函数以非常简单的方式删除标点符号: private static byte[] FilterText(byte[] arr) { List<byte> filteredBytes = new List<byte>(); int j = 0; //index for filteredArray

我最近发现了LINQ,我发现它的使用非常有趣。目前,我有以下功能,我不确定它是否会更有效,毕竟,产生相同的输出

你能告诉我你对此的看法吗

该函数以非常简单的方式删除标点符号:

private static byte[] FilterText(byte[] arr)
    {
        List<byte> filteredBytes = new List<byte>();
        int j = 0; //index for filteredArray

        for (int i = 0; i < arr.Length; i++)
        {
            if ((arr[i] >= 65 && arr[i] <= 90) || (arr[i] >= 97 && arr[i] <= 122) || arr[i] == 10 || arr[i] == 13 || arr[i] == 32)
            {
                filteredBytes.Insert(j, arr[i]) ;
                j++;
            }
        }

        //return the filtered content of the buffer
        return filteredBytes.ToArray();
    }
专用静态字节[]过滤器文本(字节[]arr)
{
List filteredBytes=新列表();
int j=0;//filteredArray的索引
对于(int i=0;i如果((arr[i]>=65&&arr[i]=97&&arr[i]=65&&a=97&&aLINQ通常比简单循环和过程代码的效率稍低,但差别通常很小,而且简洁易读通常值得将简单的投影和过滤转换为LINQ


如果性能真的很重要,请测量它,然后自己决定LINQ代码的性能是否足够。

LINQ非常适合保持简单。从性能角度看,如果您开始对列表、数组等进行大量转换,它确实会成为一个问题

MyObject.where(...).ToList().something().ToList().somethingelse.ToList();

众所周知,这是一个杀手,请尽可能晚地转换为最终列表。

螺钉性能,LINQ是令人惊讶的,因为:

private static bool IsAccepted(byte b)
{
    return (65 <= b && b <= 90) || 
           (97 <= b && b <= 122) || 
           b == 10 || b == 13 || b == 32;
}

arr.Where(IsAccepted).ToArray(); // equivalent to FilterText(arr)
private static bool被接受(字节b)
{

返回(65在大多数情况下,我同意@MarkByers。Linq的效率会比过程代码低一点。一般来说,缺陷可以追溯到表达式树的编译。然而,可读性和时间改进在99%的情况下是值得的。当遇到性能问题时,请进行基准测试、修改和重新基准测试rk

话虽如此,LINQ与lambdas和匿名委托关系非常密切。这些特性被谈论和经常被谈论,就好像它们是同一件事一样。有一些情况下,这些构造比过程代码更快。看起来你的示例可能就是其中之一。我将重写你的code如下:

private static byte [] FilterText2(byte[] arr) {

   return arr.Where( a=> (a >= 65 && a <= 90)  || 
                         (a >= 97 && a <= 122) || 
                          a == 10 || a == 13   || a == 32
                  ).ToArray();
}
专用静态字节[]FilterText2(字节[]arr){
返回arr.Where(a=>(a>=65&&a=97&&a只需将
aspallel()
添加到查询的开头。如果希望以牺牲某些性能为代价保留原始订单,还可以添加
AsOrdered()
。例如,以下LINQ语句:

arr.Where(IsAccepted).ToArray();
可以写为:

arr.AsParallel().AsOrdered().Where(IsAccepted).ToArray();
您只需确保:


每一个好的命令式代码都比好的声明性代码更节省时间和空间,因为声明性代码必须转换为命令式代码(除了您拥有一台Prolog机器……您可能没有,因为您正在询问.Net:-))

但是,如果您可以用比使用循环更简单、更可读的方式使用LINQ解决问题,那么这是值得的

var actualPrices = allPrices
    .Where(price => price.ValidFrom <= today && price.ValidTo >= today)
    .Select(price => price.PriceInUSD)
    .ToList();
var实际价格=所有价格
.Where(price=>price.ValidFrom=今天)
.Select(price=>price.PriceInUSD)
.ToList();
它是“一行”,第一眼就可以看出它在做什么。声明一个新集合,循环使用旧集合,编写if并向新集合添加内容都不是。因此,如果您不想节省每一毫秒(您可能不想这样做,因为您使用的是.Net而不是带有嵌入式ASM的C),这就是一个胜利.而且LINQ是高度优化的-有更多的代码基-一个用于集合,一个用于XML,一个用于SQL…,所以它通常不会慢很多。没有理由不使用它


一些LINQ表达式可以很容易地使用并行LINQ进行并行化,几乎是“免费的”(=没有更多的代码,但并行开销仍然存在,所以请考虑一下)。

为什么有
j
?只需使用
Add
而不是
Insert
,您就可以省去该计数器。您可能应该替换
.Insert(j,
部分为
。添加(
并删除
j
计数器。是的,谢谢你,我刚刚修改了代码,甚至没有安排!而且,由于大多数字符将被保留,你应该用
新列表(arr.Length)替换
新列表()
。这将避免在列表变大时必须重新创建其内部结构。您不需要这样做。传递给
列表(int)
构造函数的参数仅指示容量(在不调整大小的情况下可容纳的容量),而不是它实际能容纳多少。同意@Mark。使用linq会比调试代码花费更多的时间。除非你会调试复杂的linq查询,这可能也很棘手-这并不意味着我不会使用它,尽管+1:这一点很好。如果你需要对返回的序列进行进一步的筛选/排序/操作,那么最好将其作为
可枚举
返回,而不使用
ToArray()
@Douglas我想您的意思是
IEnumerable
Enumerable
是一个静态类),但另有约定。
var queryA = from num in numberList.AsParallel()
             select ExpensiveFunction(num); //good for PLINQ

var queryB = from num in numberList.AsParallel()
             where num % 2 > 0
             select num; //not as good for PLINQ
var actualPrices = allPrices
    .Where(price => price.ValidFrom <= today && price.ValidTo >= today)
    .Select(price => price.PriceInUSD)
    .ToList();