首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为List<Object>找到和查找索引痛苦的慢为什么?

为List<Object>找到和查找索引痛苦的慢为什么?
EN

Stack Overflow用户
提问于 2012-02-17 15:40:48
回答 4查看 3.7K关注 0票数 1

Im正在使用密集列表的项目中工作,我试图通过名称(即对象的成员)来查找对象。

我的代码在不使用单个for-next循环(函数find1)搜索它的情况下工作,但是我发现,使用内置查找找到的代码是可能的,而且代码可以工作。然而,它感觉有点慢。所以,我做了一个测试速度的项目:

我有下一个代码

代码语言:javascript
运行
复制
    public List<MyObject> varbig = new List<MyObject>();
    public Dictionary<string,string> myDictionary=new Dictionary<string, string>();
    public Form1() {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
        myDictionary.Clear();
        varbig.Clear();

        for (int i = 0; i < 5000; i++) {
            varbig.Add(new MyObject("name" + i.ToString(),"value"+i.ToString()));
            myDictionary.Add("name" + i.ToString(), i.ToString());
        }
        // first test
        var start1 = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss=find1("name499");
        }
        var end1 = Environment.TickCount;
        Console.WriteLine("time  1 :" + (end1 - start1));
        // second test
        var start2 = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss=find2("name499");
        }
        var end2 = Environment.TickCount;
        Console.WriteLine("time  2 :" + (end2 - start2));
        // third test
        var start3 = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss = find3("name499");
        }
        var end3 = Environment.TickCount;
        Console.WriteLine("time  3 :" + (end3 - start3));

        // first test b
        var start1b = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss=find1("name4999");
        }
        var end1b = Environment.TickCount;
        Console.WriteLine("timeb 1 :" + (end1b - start1b));
        // second test
        var start2b = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss=find2("name4999");
        }
        var end2b = Environment.TickCount;
        Console.WriteLine("timeb 2 :" + (end2b - start2b));
        // third test
        var start3b = Environment.TickCount;
        for (int i = 0; i < 3000; i++) {
            var ss = find3("name4999");
        }
        var end3b = Environment.TickCount;
        Console.WriteLine("timeb 3 :" + (end3b - start3b));

    }

    public int find1(string name) {
        for (int i = 0; i < varbig.Count; i++) {
            if(varbig[i].Name == name) {
                return i;
            }
        }
        return -1;
    }

    public int find2(string name) {
        int idx = varbig.FindIndex(tmpvar => Name == name);
        return idx;
    }
    public int find3(string name) {
        var ss=myDictionary[name];
        return int.Parse(ss);
    }
}

我使用下一个对象

代码语言:javascript
运行
复制
public class MyObject {
    private string _name = "";
    private string _value = "";
    public MyObject() {}

    public MyObject(string name, string value) {
        _name = name;
        _value = value;
    }

    public string Name {
        get { return _name; }
        set { _name = value; }
    }

    public string Value {
        get { return _value; }
        set { _value = value; }
    }
}

主要是做下一件事:我创建一个包含5000个元素的数组。

time 1=使用一个简单的for-next搜索499个对象(索引)。

time 2=使用List的内置函数查找搜索499

time 3=它使用字典搜索499元素。

Timeb 1、timeb 2和timeb 3也是这样做的,但是尝试搜索4999元素而不是499元素。

我跑了几次:

  • time 1 :141
  • time 2 :1248
  • time 3 :0
  • timeb 1:811H 111timeb 2:1170H 212<

>H 113timeb 3:0<代码>H 214<代码>H 115时间1:109<代码>H 216<代码>H 117时间2:1170H 218<代码>H 119时间3:0<代码>H 220H 121时间>b>1:796<><>H222代码><>H 123>时间><代码<<2b><<2b>代码<<2b>代码<<227>代码<><<227>代码><<227>代码><<227>代码><

  • ><>

(小而快)

而且,让我感到惊讶的是,函数findindex中的构建速度非常慢(在某些情况下,大约慢了10倍)。此外,字典法几乎是即时的。

我的问题是,为什么?是因为谓语吗?

EN

回答 4

Stack Overflow用户

发布于 2012-02-17 16:09:14

问题就在这一行上:

代码语言:javascript
运行
复制
int idx = varbig.FindIndex(tmpvar => Name == name);

Name == name是错误的,你应该写tmpvar.Name == name代替。

在代码中,您将name参数与表单的Name属性进行比较;它们显然不同,因此该方法总是检查整个列表,而不是在找到搜索值时停止。事实上,正如您所看到的数字一样,find2()所花费的时间基本上总是相等的。

关于字典,它显然比其他方法更快,因为字典是专门为提供快速键访问而构建的内存结构。

实际上,它们接近O(1)时间复杂度,而循环列表的时间复杂度等于O(n)

票数 2
EN

Stack Overflow用户

发布于 2012-02-17 16:03:52

  • Find1使用的是一个简单的for( i=0 to count)方法
  • Find2使用内置的查找方法(这正是上面的find1 ),只不过您已经传递了一个谓词,我认为它正在减慢它的速度。使用字典的
  • Find3,我认为没有计时器是最快的,因为字典在封面下使用哈希表,其中包含0(1)查找(内容时间)

票数 1
EN

Stack Overflow用户

发布于 2012-02-17 16:08:32

代码中有错误-- find2方法使用Form.Name进行比较,而不是使用集合对象名称。应该是这样的:

代码语言:javascript
运行
复制
public int find2(string name) {
    return varbig.FindIndex((obj) => obj.Name == name);
}

不使用Form.Name的结果更一致:

代码语言:javascript
运行
复制
time  1 :54
time  2 :50
time  3 :0
timeb  1 :438
timeb  2 :506
timeb  3 :0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9331184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档