查找一个对象 在对象列表中的位置是日常项目开发过程中最最常用的。大慨总结了一下,有3个常用的方法。
public class Test { public string Name { get; set; } }
一、最最常用的 依次循环查找法
private int LoopMethod() { for (int i =0; i < testList.Count; i++) { Test t = testList[i]; if (t.Name.Equals(this.findName)) { return i; } } return -1; }
二、List.IndexOf 方法
private int IndexOfMethod() { Test find = new Test() { Name = this.findName }; int i = testList.IndexOf(find); return i; }
同时需要将 Test.Equals方法进行重写
public class Test { public string Name { get; set; } public override int GetHashCode() { return base.GetHashCode(); } public override bool Equals(object obj) { if (obj == null) { return false; } if (!(obj is Test)) return false; return string.Equals(this.Name, (obj as Test).Name); } }
三、Linq方法
private int LinqMethod() { int index = testList.FindIndex(test => test.Name.Equals(this.findName)); return index; }
总结:
经过一些代码测试发现(第一种、第二种、第三种):
第一种方法的查询速度最快,再次是 Linq查询方法,再就是List.IndexOf方法
测试代码如下:
List<Test> testList; string findName = ""; testList = new List<Test>(); for (int i = 0; i < 10000; i++ ) { string name = Guid.NewGuid().ToString(); if (i == 9998) { findName = name; } Test t = new Test() { Name = name }; testList.Add(t); }
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); int index = -1; for (int k = 0; k < 100; k++) { index = LoopMethod(); } watch.Stop(); Console.WriteLine("LoopMethod: " + index.ToString() + ": " + watch.ElapsedMilliseconds.ToString()); System.Diagnostics.Stopwatch watchIndex = new System.Diagnostics.Stopwatch(); watchIndex.Start(); for (int k = 0; k < 100; k++) { index = IndexOfMethod(); } watchIndex.Stop(); Console.WriteLine("IndexOfMethod : " + index.ToString() + ": " + watchIndex.ElapsedMilliseconds.ToString()); System.Diagnostics.Stopwatch watchLinq = new System.Diagnostics.Stopwatch(); watchLinq.Start(); int res = -1; for (int k = 0; k < 100; k++) { res = LinqMethod(); } watchLinq.Stop(); Console.WriteLine("LinqMethod : " + res.ToString() + ": " + watchLinq.ElapsedMilliseconds.ToString());
运行结果:
LoopMethod: 9998: 99
IndexOfMethod : 9998: 157
LinqMethod : 9998: 114
经简单分析:
LoopMethod 耗时主要在依次循环中
IndexOfMethod 耗时主要在 Equals 方法中。
Linq方法 耗时主要在委托中
经过反编译发现:这3种方法的原理都是依次查询。
IndexOf方法:
public int IndexOf(T item) { return Array.IndexOf<T>(this._items, item, 0, this._size); } public static int IndexOf<T>(T[] array, T value, int startIndex, int count) { if (array == null) { throw new ArgumentNullException("array"); } if ((startIndex < 0) || (startIndex > array.Length)) { throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); } if ((count < 0) || (count > (array.Length - startIndex))) { throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); } return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count); } internal virtual int IndexOf(T[] array, T value, int startIndex, int count) { int num = startIndex + count; for (int i = startIndex; i < num; i++) { if (this.Equals(array[i], value)) { return i; } } return -1; }
Linq 方法核心:
public int FindIndex(Predicate<T> match)
{
return this.FindIndex(0, this._size, match);
}
public int FindIndex(int startIndex, int count, Predicate<T> match)
{
if (startIndex > this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
}
if ((count < 0) || (startIndex > (this._size - count)))
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
}
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
int num = startIndex + count;
for (int i = startIndex; i < num; i++)
{
if (match(this._items[i]))
{
return i;
}
}
return -1;
}
作者:Terry
出处:http://foolishfox.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。