0

语境

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

例如:

如果列表中有马德里和马赛城市名称等,当我按下“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;

//片段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];

根据我在 Stopwatch 类的帮助下得到的结果,更快的脚本是数字 4,但我希望它是数字 5,因为所有城市都在字典中拆分,但不幸的是字典类似乎慢慢来。

那么你们有什么方法可以提高这里的性能吗?

谢谢

4

1 回答 1

1

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

于 2012-07-12T02:08:12.250 回答