max*_*axp 24 c# linq arrays list compiler-optimization
关于效率,有谁知道编译器是否足够聪明,无法1, 3, 5
在以下代码中创建不包含循环的每次迭代的数组?
var foo = new List<int> { 1, 2, 3, 4, 5 };
foo.RemoveAll(i => new[] { 1, 3, 5 }.Contains(i));
Run Code Online (Sandbox Code Playgroud)
我更喜欢它是为了提高可读性,但不是出于性能考虑。
AAA*_*ddd 13
答案是不,它不会优化数组的分配
基本上,每次调用谓词时,它都会对编译器生成的类进行检查,并初始化一个新数组来调用Contains
(如您在此处看到的)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int[] obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
Run Code Online (Sandbox Code Playgroud)
正如@Michael Randall 已经写的那样,看起来这是不可能的。
我同意,您有问题的代码可读性很好,在 RemoveAll 方法中有列表。但是为了只有一次实例,我有三个想法:
int[] a = null;
foo.RemoveAll(i => (a ?? (a = new[] { 1, 3, 5 })).Contains(i));
Run Code Online (Sandbox Code Playgroud)
这实际上是你的,几乎不需要外部变量。
foo = foo.Except(new[] { 1, 3, 5 }).ToList();
Run Code Online (Sandbox Code Playgroud)
这实际上是使用 Linq 的非常好的解决方案。
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new[] {1, 3, 5}.Iterate(x => foo.Remove(x));
Run Code Online (Sandbox Code Playgroud)
这是我会做的事情。在我几乎所有的代码中,我都有我的扩展方法“迭代”以避免对 foreach 的需要。而且,我不想一直“列出”所有内容来制作 .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1341 次 |
最近记录: |