2017-01-03 95 views
3

我有一個函數getWords(int wrNum)這個函數從數據庫中使用實體框架返回wrNum數的隨機數,當wrNum是300時,這個函數需要10秒鐘的時間。我不明白爲什麼需要這麼多時間。請幫我的代碼有什麼問題?Asp.Net MVC我的代碼出了什麼問題?

public List<string> getWords(int wrNum) 
{ 
    IDVLTest d3 = new DVLTest(); 
    for (int i = 0; i < wrNum;i++) 
    { 
     string word = d3.getRandomWord().Text; 
     Words.Add(new WordView { Word = word, Status = WordStatus.Right }); 
    } 
    return Words.Select(w=>w.Word).ToList(); 
} 

public class DVLTest:IDVLTest 
{ 
... 
    public Word getRandomWord() 
    { 
     Random r = new Random(); 
     int i = r.Next(DVL_Entitie.Words.Count()); 
     return DVL_Entitie.Words.ToList().ElementAt(i); 
    } 
... 
} 
+1

你試過沒有每次時創建一個新的隨機對象調用getRandomWord?只需要在DVLTest的構造函數中創建一個Random對象,並在getRandomWord中只調用r.Next()。這裏的文檔https://msdn.microsoft.com/en-us/library/ctssatww(v=vs.110).aspx說:「另一種選擇是實例化一個單獨的隨機對象,用於生成所有隨機數因爲實例化一個隨機數生成器相當昂貴,所以這會產生稍好的性能。「 – ADyson

+3

而且您還可以從數據庫中檢索整個列表300次。檢索一次,然後重複使用它。 – ADyson

+0

是的,當我編輯代碼igor說如何從數據庫中得到300個相同的單詞:D謝謝;) – DVL

回答

8

因爲你是從一般每次迭代和數據庫訪問數據庫中檢索整個列表是昂貴的,因爲它發生了過程,通常通過網絡(數據庫和應用程序/處理通常不要駐留在同一臺服務器上)。您應該在for循環之外檢索一次列表,然後將檢索到的列表作爲參數傳遞給方法getRandomWord

DVL_Entitie.Words.Count() // offending line 
DVL_Entitie.Words.ToList() // offending line 
+2

不要爲每個調用做一個'新隨機',只生成一個單一的實例。 – Maarten

1

你可以做如下不要扯所有數據存儲:

return DVL_Entitie.Words.Skip(i).Take(1).FirstOrDefault; 

如果沒有太多的數據,伊戈爾的解決方案似乎是最好的。

2

正如@Igor指出

DVL_Entitie.Words.Count() // offending line 
DVL_Entitie.Words.ToList() // offending line 

DB調用拖慢這個你可以試試這個,因爲這將緩存的嘗試的其餘數目只有從DB在要求單個項目時間不是整個數據庫到一個列表,然後選擇所需的項目。

public class DVLTest : IDVLTest 
{ 

    private int wordCount = -1; 

    public Word getRandomWord() 
    { 
     Random r = new Random(); 
     int i = r.Next(this.getDBWordsCount()); 
     return DVL_Entitie.Skip(i).Take(1); 
    } 


    private int getDBWordCount() 
    { 
     if(this.wordCount < 0) 
     { 
      this.wordCount = DVL_Entitie.Words.Count(); 
     } 
     return this.wordCount; 
    } 

} 
0

感謝everyone.Know我的代碼時間爲0秒approximatly:DI喜歡你的想法@Gavin哈里森和我的代碼是現在:

public List<string> getWords(int wrNum) 
     { 
      IDVLTest d3 = new DVLTest(); 
      Random r = new Random(); 
      for (int i = 0; i < wrNum;i++) 
      { 
       string word = d3.getRandomWord(r).Text; 

       Words.Add(new WordView { Word = word, Status = WordStatus.Right }); 
      } 
      return Words.Select(w=>w.Word).ToList(); 
     } 

public class DVLTest:IDVLTest 
    { 
private int wordCount = -1; 
     private List<Word> DBWords; 

     public DVLTest() 
     { 
      DBWords = DVL_Entitie.Words.ToList(); 
     } 

     public Word getRandomWord(Random r) 
     { 
      int i = r.Next(getDBWordCount()); 
      return DBWords.ElementAt(i); 
     } 

     private int getDBWordCount() 
     { 
      if (this.wordCount < 0) 
      { 
       this.wordCount = DVL_Entitie.Words.Count(); 
      } 
      return this.wordCount; 
     } 
} 
相關問題