请教字符串数组搜索的性能问题

weenyboy 2009-03-23 11:12:33
示例代码:
public struct Person
{
public string CName;
public string EName;
public int Age;
}

class Test
{
private Person[] ArrPerson;

static void main()
{
ArrPerson = new Person[10000];
//备注:只是说明该数组非常庞大(最大可能到10万),字符串Name随机性而不是例子中的增量常数
for (int i=0;i<10000;i++)
{
ArrPerson[i].CName=i.ToString();
ArrPerson[i].EName=i.ToString();
ArrPerson[i].Age=i;
}

//需要提高效率的部分:
string MyName = "123";
for (int i=0;i<ArrPerson.Length;i++)
{
if ((MyName.CompareTo(ArrPerson[i].CName)==0)||(MyName.CompareTo(ArrPerson[i].EName)==0)
{
//找到这个人,但是不能退出循环因为可能有下一个同名的人
}
}
}


请问各位,有什么好办法能够提高查找的效率?甚至换一种全新的思路都可以,主要是要得到效率。
非常感谢。
...全文
229 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
cppfaq 2009-03-23
  • 打赏
  • 举报
回复
还是直接foreach算了
terry 2009-03-23
  • 打赏
  • 举报
回复
vs2005,不能使用linq. array也没有FindAll方法,泛型才有FindAll方法.
你可以把
ArrPerson = new Person[10000];
改为lIst<Person> 泛型,就可以使用了.
weenyboy 2009-03-23
  • 打赏
  • 举报
回复
尝试了FindAll办法,可惜我的目标程序运行在WinCE系统上,Array并不提供FindAll方法,感觉有点奇怪。
weenyboy 2009-03-23
  • 打赏
  • 举报
回复
请教,vs2005是否可以使用linq?在更新到.net 3.0以上的情况下?
我测试发现ide不能识别linq代码
wuyi8808 2009-03-23
  • 打赏
  • 举报
回复
可参考在线 msdn:
http://msdn.microsoft.com/zh-cn/library/1kkxfxdd.aspx

.NET Framework 类库
Array.FindAll <T> 方法

更新:2007 年 11 月

检索与指定谓词定义的条件匹配的所有元素。

JaggerLee 2009-03-23
  • 打赏
  • 举报
回复
关注,LINQ是好办法
wuyi8808 2009-03-23
  • 打赏
  • 举报
回复
试试 Array.FindAll<T>() 泛型方法,看看能不能提高效率。
vrhero 2009-03-23
  • 打赏
  • 举报
回复
你这不是字符串数组..这种当然最好是用Linq...

var result=from p in ArrPerson
where p.CName==0 || p.EName==0
select p;
weenyboy 2009-03-23
  • 打赏
  • 举报
回复
结帖了,谢谢各位
最终还是回到C的老路,使用String.IndexOf的办法,通过CName和EName上面建立一个长字符串来搞定了。
zzxap 2009-03-23
  • 打赏
  • 举报
回复
[code=C#]
string MyName = "123";
for (int i=0;i <ArrPerson.Length;i++)
{
if ((MyName.CompareTo(ArrPerson[i].CName)==0)||(MyName.CompareTo(ArrPerson[i].EName)==0)
{
//找到这个人,但是不能退出循环因为可能有下一个同名的人
}
}

改成
string MyName = "123";
if(MyName.CompareTo(ArrPerson[i].CName)==0)
{
for (int i=0;i <ArrPerson.Length;i++)
{

}
}

if(MyName.CompareTo(ArrPerson[i].EName)==0)
{
for (int i=0;i <ArrPerson.Length;i++)
{

}

}
这样会快点

[/CODE]
shrinerain 2009-03-23
  • 打赏
  • 举报
回复
如果你的程序是"插入删除少, 搜索多", 那么考虑使用有序数组, 以姓名作为关键字排序, 进行二分查找.

当然, 如果你算法功底不错的话, 考虑用红黑树等数据结构存储你的struct, 能同时提高插入删除效率.


如果你空间不吃紧的话, 建索引是更好的方式, 按照CName, EName分别建立索引, 如果你空间足够的话, 建立多重索引. 只不过索引维护要更加麻烦一些.


至于用for还是foreach, 这个不会实质上提高你的算法性能. 带来的影响几乎可以忽略不计.
vrhero 2009-03-23
  • 打赏
  • 举报
回复
Linq还有更优化的写法...这个比Linq查询式快一点...它们和循环的效率其实相差无几,10万数据也就是1毫秒左右的差距...
var result=ArrPerson.TakeWhile(p => p.CName.Equals(MyName) || p.EName.Equals(eName));


不过lz是要在.NET CF中实现,那你还是老老实实循环吧...
wangping_li 2009-03-23
  • 打赏
  • 举报
回复
10w记录测试差不多foreach所花的时间是for循环的36%,所以用foreach应该要快些
wangping_li 2009-03-23
  • 打赏
  • 举报
回复
对,linq我也觉得并不是提高性能的,自己写的匿名方法,它还是自己去翻译,有时候反而慢了,只是操作方便而已
另外List的public List<T> FindAll (Predicate<T> match)方法和循环是一样的,运算复杂度也是O(n),只是写法简单而已,用foreach遍历List <Person>看看是否还有提高
冷月孤峰 2009-03-23
  • 打赏
  • 举报
回复
想到的只有foreach循环!
路人乙e 2009-03-23
  • 打赏
  • 举报
回复
个人看法:
Linq的出现并不是为了提高性能,而是为了“简便”
简便的背后必然要牺牲效率,所以Linq好用,但没效率

find的机制也是循环,未必效率就高

一般的查询使用最简单的循环效率反而最好,但建议使用foreach
可以做个简单的实验:
        static void Main()
{
List<string> list = new List<string>();
string[] ss = new string[1000000];
for (int i = 0; i < 1000000; i++)
{
list.Add("item-" + i.ToString());
ss[i] = "item-" + i.ToString();
}
Console.WriteLine(DateTime.Now.Millisecond.ToString());
list.FindAll(Ends);
Console.WriteLine(DateTime.Now.Millisecond.ToString());
foreach (string s in ss)
{
if (s == "item-9999") { }
}
Console.WriteLine(DateTime.Now.Millisecond.ToString());
}
static bool Ends(string s)
{
if (s == "item-9999") return true;
else return false;
}
liusichen_0 2009-03-23
  • 打赏
  • 举报
回复
关注中
weenyboy 2009-03-23
  • 打赏
  • 举报
回复
用了一下List<Person>泛型,速度提高大概20%,但仍然难以达到想要的效率

看来我尝试一下组织一个大型字符串,然后用string.IndexOf方法是否有更高的效率了。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧