2012-04-09 17 views
0

コンテキスト検索アルゴリズム

私はメモリに(名前で)注文したのリストの市のオブジェクトを持っている、と私は少しの提案のように、私は文字を入力すると、これらの都市のリストを取得する必要がありますボックス。

例:

私は、返されたリストにマドリードとマルセイユを取得する必要があります「M」の文字を押すと、リストには、他の人の間でマドリードとマルセイユ都市名を持っている場合。さて、数年前には、もっと速く動かすために、スレッドを2本走らせていましたが、最近は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番になることを期待していました。残念ながら辞書のクラスは遅くなるようです。

ここでパフォーマンスを改善する方法はありますか?

おかげ

+0

いくつの都市をテストしましたか? – svick

+0

最適化は単純さを犠牲にします。私は、単純なplinq解(3)との違いが犠牲に値するとはほとんど想像もできません。それとも彼らは?そして:あなたは、ユーザーが最初に国を選択してから都市を選ぶようにすることはできませんか? –

+0

はい、減速が目立つほど大きくなければ、3が最善の選択と思われます。しかし、あなたは都市がすでに名前で分類されていると言います。その場合、バイナリ検索を使用して検索を開始する場所を探してから、plinqの有無にかかわらずそこから移動できますか? – Jamie

答えて

1

あなたがtrieを使用してみましたか?最初のn文字を指定してn個の操作のリストを表すsubtrieを検索し、それを並行してリストに変換することができます。