搜索算法

时间:2012-04-09 08:20:30

标签: c# linq optimization task-parallel-library

上下文

我在内存中有一个有序(按名称)城市对象的列表,我需要在输入字符时得到这些城市的列表,有点像建议框。

例如:

如果列表中包含马德里和马赛的城市名称,当我按下“M”字符时,我需要将马德里和马赛列入返回的列表中。好吧,在几年前,我会运行几个线程,以使事情变得更快,但现在,使用LINQ和TPL,经过几次测试后,我得出结论,更快的方法是使用这些新库而不是手动执行。因此,我编写了一些脚本并相互测试。剪切的每个代码都在自己的类中运行:

//Snippet 1

            List<ICity> objCities = new List<ICity>();

            foreach (ICity objCity in this.m_objCities)
            {
                if (objCity.Name.Length >= pName.Length)
                {
                    if (objCity.Name.Substring(0, pName.Length).Equals(pName))
                    {
                        objCities.Add(objCity);
                    }
                }
                else if (objCitys.Count > 0)
                {
                    break;
                }
            }

            return objCities;

//代码段2

                ICollection<ICity> objCities = base.m_objCities.Where((ICity pCity) =>
            {
                bool bFound = false;

                if (pCity.Name.Length >= pName.Length)
                {
                    bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                }

                return bFound;

            }).ToList();

            return objCities;

//代码段3

                ICollection<ICity> objCities = base.m_objCities.AsParallel().Where((ICity pCity) =>
            {
                bool bFound = false;

                if (pCity.Name.Length >= pName.Length)
                {
                    bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                }

                return bFound;

            }).ToList();

            return objCities;

// Snippet 4

            //Used as a class member
            private List<ICollection<IStation>> objLastCities = new List<ICollection<IStation>>();

            int iNameCount = pName.Length;
            ICollection<ICity> objCities = null;

            if (this.m_iLastNameCount == 0 || iNameCount == 1)
            {
                objCities = base.m_objCities.Where((ICity pCity) =>
                                {
                                    bool bFound = false;

                                    if (pCity.Name.Length >= pName.Length)
                                    {
                                        bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                                    }

                                    return bFound;

                                }).ToList();

                this.objLastCities.Clear();
                this.objLastCities.Add(objCities);

                this.m_iLastNameCount = 1;
            }
            else
            {
                if (iNameCount > this.m_iLastNameCount)
                {
                    objCities = this.objLastCities[this.m_iLastNameCount - 1].Where((ICity pCity) =>
                                {
                                    bool bFound = false;

                                    if (pCity.Name.Length >= pName.Length)
                                    {
                                        bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                                    }

                                    return bFound;

                                }).ToList();

                    this.objLastCities.Add(objCities);

                    this.m_iLastNameCount++;
                }
                else
                {
                    objCities = base.m_objCities.Where((ICity pCity) =>
                                {
                                    bool bFound = false;

                                    if (pCity.Name.Length >= pName.Length)
                                    {
                                        bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                                    }

                                    return bFound;

                                }).ToList();

                    this.objLastCities.RemoveAt(iNameCount - 1);

                    objCities = this.objLastCities[iNameCount - 1];

                    this.m_iLastNameCount--;
                }

                this.objLastCities.Add(objCities);
            }

            return this.objLastCities[this.objLastCities.Count - 1];

//代码段5

        ////Member objects
        private List<ICollection<ICity>> objLastCities = new List<ICollection<ICity>>();
        private int m_iLastNameCount = 0;
        private Dictionary<char, ICollection<ICity>> m_objCitiesByKey = null;


        ////Code that runs in the class contructor
        this.m_objCitiesByKey.Add('A', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'A'; }).ToList());
        this.m_objCitiesByKey.Add('B', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'B'; }).ToList());
        this.m_objCitiesByKey.Add('C', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'C'; }).ToList());
        this.m_objCitiesByKey.Add('D', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'D'; }).ToList());
        this.m_objCitiesByKey.Add('E', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'E'; }).ToList());
        this.m_objCitiesByKey.Add('F', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'F'; }).ToList());
        this.m_objCitiesByKey.Add('G', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'G'; }).ToList());
        this.m_objCitiesByKey.Add('H', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'H'; }).ToList());
        this.m_objCitiesByKey.Add('I', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'I'; }).ToList());
        this.m_objCitiesByKey.Add('J', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'J'; }).ToList());
        this.m_objCitiesByKey.Add('K', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'K'; }).ToList());
        this.m_objCitiesByKey.Add('L', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'L'; }).ToList());
        this.m_objCitiesByKey.Add('M', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'M'; }).ToList());
        this.m_objCitiesByKey.Add('N', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'N'; }).ToList());
        this.m_objCitiesByKey.Add('O', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'O'; }).ToList());
        this.m_objCitiesByKey.Add('P', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'P'; }).ToList());
        this.m_objCitiesByKey.Add('Q', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'Q'; }).ToList());
        this.m_objCitiesByKey.Add('R', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'R'; }).ToList());
        this.m_objCitiesByKey.Add('S', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'S'; }).ToList());
        this.m_objCitiesByKey.Add('T', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'T'; }).ToList());
        this.m_objCitiesByKey.Add('U', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'U'; }).ToList());
        this.m_objCitiesByKey.Add('V', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'V'; }).ToList());
        this.m_objCitiesByKey.Add('W', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'W'; }).ToList());
        this.m_objCitiesByKey.Add('X', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'X'; }).ToList());
        this.m_objCitiesByKey.Add('Y', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'Y'; }).ToList());
        this.m_objCitiesByKey.Add('Z', base.m_objCities.Where((ICity pCity) => { return pCity.Name[0] == 'Z'; }).ToList());


        ////Code Running in a Methods
        int iNameCount = pName.Length;
        ICollection<ICity> objCities = null;

        if (this.m_iLastNameCount == 0 || iNameCount == 1)
        {
            objCities = this.m_objCitiesByKey[pName[0]];

            this.objLastCities.Clear();
            this.objLastCities.Add(objCities);

            this.m_iLastNameCount = 1;
        }
        else
        {
            if (iNameCount > this.m_iLastNameCount)
            {
                objCities = this.objLastCities[this.m_iLastNameCount - 1].Where((ICity pCity) =>
                                                                            {
                                                                                bool bFound = false;

                                                                                if (pCity.Name.Length >= pName.Length)
                                                                                {
                                                                                    bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                                                                                }

                                                                                return bFound;

                                                                            }).ToList();

                this.objLastCities.Add(objCities);

                this.m_iLastNameCount++;
            }
            else
            {
                objCities = base.m_objCities.Where((ICity pCity) =>
                                                                            {
                                                                                bool bFound = false;

                                                                                if (pCity.Name.Length >= pName.Length)
                                                                                {
                                                                                    bFound = pCity.Name.Substring(0, pName.Length).Equals(pName);
                                                                                }

                                                                                return bFound;

                                                                            }).ToList();


                this.objLastCities.RemoveAt(iNameCount - 1);

                objCities = this.objLastCities[iNameCount - 1];

                this.m_iLastNameCount--;
            }

            this.objLastCities.Add(objCities);
        }

        return this.objLastCities[this.objLastCities.Count - 1];

根据我在秒表类的帮助下获得的结果,更快的脚本是数字4,但我期望它是数字5,因为所有的城市都在字典中分开,但不幸的是字典上课似乎有点慢。

那么你们有没有办法改善这里的表现呢?

由于

1 个答案:

答案 0 :(得分:1)

您是否尝试使用trie?您可以给前n个字母搜索在n个操作中找到代表该列表的子集,然后将其转换为并行列表