- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
( This question arises from a discussion that started here )
我正在比较寻找 true
的时间List<bool>
中的值使用 List.Contains()
与那些用于手卷循环。
我看到的结果与其他人报告的结果不同。我已经在几个系统上试过了,在我试过的所有系统上,循环似乎快了 2 到 3.5 倍。这些系统的范围从使用 .Net 4 运行 XP 的 5 年前笔记本电脑到最近运行 Windows 8 和 .Net 4.5 的 PC。
其他人报告了不同的结果,即 List.Contains()
与循环的速度大致相同或略快。
这是我的测试代码。
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main()
{
int size = 10000000;
int count = 10;
List<bool> data = new List<bool>(size);
for (int i = 0; i < size; ++i)
data.Add(false);
var sw = new Stopwatch();
for (int trial = 0; trial < 5; ++trial)
{
sw.Restart();
for (int i = 0; i < count; ++i)
TestViaLoop(data);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds + " TestViaLoop()");
sw.Restart();
for (int i = 0; i < count; ++i)
TestViaListContains(data);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds + " TestViaListContains()");
Console.WriteLine();
}
}
static bool TestViaLoop(List<bool> data)
{
for (int i = 0; i < data.Count; ++i)
if (data[i])
return true;
return false;
}
static bool TestViaListContains(List<bool> data)
{
return data.Contains(true);
}
}
}
要测试此代码,您应该将其编译为 x86 RELEASE 版本,并从调试器外部运行它。
以下是我使用 .Net 4.5 框架在 Windows 8 x64 PC 上的结果(尽管我在 .Net 4 上得到了类似的结果):
Times are in milliseconds
126 TestViaLoop()
441 TestViaListContains()
122 TestViaLoop()
428 TestViaListContains()
131 TestViaLoop()
431 TestViaListContains()
138 TestViaLoop()
426 TestViaListContains()
122 TestViaLoop()
439 TestViaListContains()
如您所见,该循环在我的系统上花费了大约 1/3 的时间。
现在如果我们使用 Resharper
查看 List.Contains()
的执行情况它看起来像这样:
bool Contains(T item)
{
if (item == null)
{
for (int j = 0x0; j < this._size; j++)
{
if (this._items[j] == null)
{
return true;
}
}
return false;
}
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0x0; i < this._size; i++)
{
if (comparer.Equals(this._items[i], item))
{
return true;
}
}
return false;
}
虽然它正在使用 Comparer.Equals()
(这应该使它比循环慢)它也在使用私有(private) _items[]
数组,这避免了将用于我的循环实现的索引范围检查。
我有三个问题:
List.Contains()
快得多? ?这不仅仅是我的学术兴趣,因为我编写的代码处理大量数字数据并且需要尽可能快,而这正是我需要了解的事情。 (注意:是的,我分析了一些事情,并且只尝试优化需要优化的东西......我知道过早优化的问题。)
[编辑]
我突然想到这可能与处理器有关。我试过的所有系统都有 Intel 处理器,尽管型号非常不同,从 3.8GHz 的四核到 1.6GHz 的 Pentium M 单核……
对于那些看到循环运行速度较慢的人,您是否在运行 Intel 处理器?
最佳答案
它使用 GenericEqualityComparer,如果我们看一下 Equals 方法的实现是这样的:
public override bool Equals(T x, T y)
{
if ((object) x != null)
{
if ((object) y != null)
return x.Equals(y);
else
return false;
}
else
return (object) y == null;
}
当它检查对象是否不等于 null 时,它会对它们进行装箱,你会得到两个装箱操作。此 IL 代码显示了它的外观:
IL_0002: box !T
IL_0007: ldnull
IL_0008: ceq
由 280Z28 编辑:相同方法的 CIL 在 .NET 4.5 中略有不同。
public override bool Equals(T x, T y)
{
if (x != null)
return ((y != null) && x.Equals(y));
if (y != null)
return false;
return true;
}
这是 IL。对于查看 Reflector 的任何人,请注意 brfalse.s
和 brnull.s
是相同的指令。
L_0000: ldarg.1
L_0001: box !T
L_0006: brnull.s L_0021
...
基线 JIT 编译器不会优化开箱操作,但我没有使用 NGen 或优化编译器检查它们是否这样做。
关于c# - List.Contains() 的循环实现看起来比内置的更快。是吗?如果是这样,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16062154/
我想使用 R 预定义这样的列表 DATA<-list( list(list(),list(),list()), list(list(),list(),list()), list(list(),l
如何将一个列表添加到另一个列表,返回一个列表的列表? foo :: [a] -> [a] -> [[a]] 例如,我想要的结果是: foo [1,2] [3,4] 将是 [[1,2], [3,4]]。
我还没有在这里找到类似问题的解决方案,所以我会寻求你的帮助。 有 2 个列表,其中之一是列表列表: categories = ['APPLE', 'ORANGE', 'BANANA'] test_re
这个问题不同于Converting list of lists / nested lists to list of lists without nesting (这会产生一组非常具体的响应,但无法解决
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在下面的代码中,get()被调用并将其结果分配给类型为 List> 的变量. get()返回 List>并在类型参数为 T 的实例上调用设置为 ? ,所以它应该适合。 import java.util
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在insufficiently-polymorphic 作者说: def foo[A](fst: List[A], snd: List[A]): List[A] There are fewer way
我有下面的代码有效。 class ListManipulate(val list: List, val blockCount: Int) { val result: MutableList>
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
在 scala (2.9) 中转换列表列表的最佳方法是什么? 我有一个 list : List[List[A]] 我想转换成 List[A] 如何递归地实现这一点?或者还有其他更好的办法吗? 最佳答案
我编写了这个函数来确定给定元素是否存储在元组列表的列表中,但目前它只搜索第一个列表。我将如何搜索其余列表? fun findItem (name : command, ((x,y)::firstlis
我创建了一个类名 objectA,它有 4 个变量:约会时间;字符串文本;变量 1,变量 2 我需要创建一个 ObjectA() 列表。然后首先按时间对它们进行分组,其次按 var1,然后按 var2
我有一套说法 char={'J','A'} 和列表的列表 content = [[1,'J', 2], [2, 'K', 3], [2, 'A', 3], [3,'A', 9], [5, 'J', 9
我有以下列表 List >>> titles = new ArrayList >>> ();我想访问它的元素,但我不知道该怎么做.. 该列表有 1 个元素,它又包含 3 个元素,这 3 个元素中的
转换 List[List[Long]] 的最佳方法是什么?到 List[List[Int]]在斯卡拉? 例如,给定以下类型列表 List[List[Long]] val l: List[List[Lo
我有一个来自 Filereader (String) 的 List-List,如何将其转换为 List-List (Double):我必须返回一个包含 line-Array 的第一个 Values 的
我收集了List> 。我需要将其转换为List> 。这是我尝试过的, List> dataOne = GetDataOne(); var dataTwo = dataOne.Select(x => x
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
我是一名优秀的程序员,十分优秀!