一个数据库表(id,name,…)中有10万条记录,查找name=’guoguo‘可能需要很长时间,但是如果对name建立了索引,那么再用name=’guoguo‘来查询将变得非常快(有多快?自己可以去试试)。
相应的,有时候我们的代码里面会用到List,Array来存储一组数据。我们以一个例子来说明一下。
定义数据类型:
public class UserInfo
{
public int ID { get;
set;
}
public string Name { get;
set;
}
public int Age { get;
set;
}
}
【C#中如何优化列表遍历速度】示例代码有个前提:name不会重复。从List中按照name找到对应的UserInfo可以用以下代码:
List _userinfos;
public UserInfo GetUserInfoByName(string name){for (int i = 0;
i < _userinfos.Count;
i++){UserInfo ui = _userinfos[i];
if (ui.Name == name){return ui;
}}return null;
} public UserInfo GetUserInfoByName_Find(string name){return _userinfos.Find((temp) =>{return temp.Name == name;
});
}
两个方法其实都是使用遍历列表的方式去比较、查找;我做了实验,如果列表中有10万条记录,分别执行“查找第5万个元素”1000遍的耗时为:
GetUserInfoByName
|
1877毫秒
|
GetUserInfoByName_Find
|
2290毫秒
|
也就是说平均一次要2毫秒左右(Find效率还更低);
OK,接下来我们要试着借鉴数据库的方式给List建立索引。
public List Userinfos{get { return _userinfos;
}set{_userinfos = value;
MakeIndex();
}} Dictionary _userIndex;
/// /// 建立索引/// private void MakeIndex(){Dictionary userIndex = new Dictionary();
foreach (var item in _userinfos){userIndex.Add(item.Name, item);
}_userIndex = userIndex;
}
MakeIndex方法在Userinfos的set属性器里面调用;那么查询的方法就应该这么写:
public UserInfo GetUserInfoByNameEx(string name){return _userIndex[name];
}
这么简单?对,就是这么简单,而且,效率特别高。与上面的两个方法一起进行比较:
文章图片
建立索引+查找10万次=36毫秒!
原因就是Dictionary[Key]方法的时间复杂度为O(1),几乎不耗时。
注意:本示例为了代码简洁,对于key重复,null引用等等都没有判断,实际编码过程中请注意考虑这些情况。
以下是示例的所有代码:
文章图片
文章图片
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApplication1{class Program{ static void Main(string[] args){List userinfos = new List();
//创建10万个数据for (int i = 0;
i < 10 * 10000;
i++){UserInfo ui = new UserInfo();
ui.ID = i;
ui.Name = Guid.NewGuid().ToString();
userinfos.Add(ui);
}UserUtil util = new UserUtil();
//用于计时Stopwatch sw = new Stopwatch();
sw.Start();
util.Userinfos = userinfos;
sw.Stop();
Console.WriteLine(string.Format("建立索引MakeIndex耗时:{0}毫秒", sw.ElapsedMilliseconds));
//以第5万个名字作为要查找的名字string nameToFind = userinfos[5 * 10000].Name;
sw.Reset();
sw.Start();
for (int i = 0;
i < 1000;
i++){util.GetUserInfoByName(nameToFind);
}sw.Stop();
Console.WriteLine(string.Format("执行1000次GetUserInfoByName耗时:{0}毫秒", sw.ElapsedMilliseconds));
sw.Reset();
sw.Start();
for (int i = 0;
i < 1000;
i++){util.GetUserInfoByName_Find(nameToFind);
}sw.Stop();
Console.WriteLine(string.Format("执行1000次GetUserInfoByName_Find耗时:{0}毫秒", sw.ElapsedMilliseconds));
sw.Reset();
sw.Start();
for (int i = 0;
i < 10 * 10000;
i++){util.GetUserInfoByNameEx(nameToFind);
}sw.Stop();
Console.WriteLine(string.Format("执行10万次GetUserInfoByNameEx耗时:{0}毫秒", sw.ElapsedMilliseconds));
Console.ReadKey();
}} public class UserUtil{List _userinfos;
public List Userinfos{get { return _userinfos;
}set{_userinfos = value;
MakeIndex();
}} Dictionary _userIndex;
public UserInfo GetUserInfoByName(string name){for (int i = 0;
i < _userinfos.Count;
i++){UserInfo ui = _userinfos[i];
if (ui.Name == name){return ui;
}}return null;
} public UserInfo GetUserInfoByName_Find(string name){return _userinfos.Find((temp) =>{return temp.Name == name;
});
}/// /// 建立索引/// private void MakeIndex(){Dictionary userIndex = new Dictionary();
foreach (var item in _userinfos){userIndex.Add(item.Name, item);
}_userIndex = userIndex;
} public UserInfo GetUserInfoByNameEx(string name){return _userIndex[name];
} } public class UserInfo{public int ID { get;
set;
}public string Name { get;
set;
}public int Age { get;
set;
}}}
示例代码
转载于:https://www.cnblogs.com/jifengg/archive/2013/05/14/3077765.html
推荐阅读