2010-05-25 22 views
2

我有一個結果集永遠不會超過500;從Web服務返回的結果被分配給搜索結果對象。在C中爲搜索結果選擇一種類型#

來自webservice的數據大約是2MB;我想使用的位數大約是每個記錄的三分之一,所以這允許我緩存並快速操作它。

我希望能夠進行排序和過濾用的開銷最少的結果,並儘可能快,所以我用了VCSKICKS計時類來衡量他們的表現

   Average  Total (10,000) 
Type  Create Sort  Create Sort 
HashSet 0.1579 0.0003 1579 3 
IList  0.0633 0.0002 633  2 
IQueryable 0.0072 0.0432 72  432 

測量使用http://www.vcskicks.com/algorithm-performance.php

我通過for循環創建了哈希集,通過Web服務響應(添加到哈希集)。

列表& IQueryable是使用LINQ創建的。

問題 我可以理解爲什麼HashSet需要更長的時間來創建(foreach循環與linq);但爲什麼IQueryable需要比其他兩個更長的排序時間;最後是否有更好的方法來分配HashSet。

感謝

實際程序從控制檯

public class Program 
{ 
    private static AuthenticationHeader _authHeader; 
    private static OPSoapClient _opSession; 
    private static AccommodationSearchResponse _searchResults; 

    private static HashSet<SearchResults> _myHash; 
    private static IList<SearchResults> _myList; 
    private static IQueryable<SearchResults> _myIQuery; 

    static void Main(string[] args) 
    { 
     #region Setup WebService 
     _authHeader = new AuthenticationHeader { UserName = "xx", Password = "xx" }; 
     _opSession = new OPSoapClient(); 


     #region Setup Search Results 

     _searchResults = _opgSession.SearchCR(_authHeader, "ENG", "GBP", "GBR"); 

     #endregion Setup Search Results 

     #endregion Setup WebService 


     // HASHSET 
     SpeedTester hashTest = new SpeedTester(TestHashSet); 
     hashTest.RunTest(); 
     Console.WriteLine("- Hash Test \nAverage Running Time: {0}; Total Time: {1}", 
      hashTest.AverageRunningTime, 
      hashTest.TotalRunningTime); 

     SpeedTester hashSortTest = new SpeedTester(TestSortingHashSet); 
     hashSortTest.RunTest(); 
     Console.WriteLine("- Hash Sort Test \nAverage Running Time: {0}; Total Time: {1}", 
      hashSortTest.AverageRunningTime, 
      hashSortTest.TotalRunningTime); 

     // ILIST 
     SpeedTester listTest = new SpeedTester(TestList); 
     listTest.RunTest(); 
     Console.WriteLine("- List Test \nAverage Running Time: {0}; Total Time: {1}", 
      listTest.AverageRunningTime, 
      listTest.TotalRunningTime); 

     SpeedTester listSortTest = new SpeedTester(TestSortingList); 
     listSortTest.RunTest(); 
     Console.WriteLine("- List Sort Test \nAverage Running Time: {0}; Total Time: {1}", 
      listSortTest.AverageRunningTime, 
      listSortTest.TotalRunningTime); 

     // IQUERIABLE 
     SpeedTester iqueryTest = new SpeedTester(TestIQueriable); 
     iqueryTest.RunTest(); 
     Console.WriteLine("- iquery Test \nAverage Running Time: {0}; Total Time: {1}", 
      iqueryTest.AverageRunningTime, 
      iqueryTest.TotalRunningTime); 

     SpeedTester iquerySortTest = new SpeedTester(TestSortableIQueriable); 
     iquerySortTest.RunTest(); 
     Console.WriteLine("- iquery Sort Test \nAverage Running Time: {0}; Total Time: {1}", 
      iquerySortTest.AverageRunningTime, 
      iquerySortTest.TotalRunningTime); 
    } 

    static void TestHashSet() 
    { 
     var test = _searchResults.Items; 

     _myHash = new HashSet<SearchResults>(); 

     foreach(var x in test) 
     { 
      _myHash.Add(new SearchResults 
            { 
             Ref = x.Ref, 
             Price = x.StandardPrice 
            }); 
     } 

    } 

    static void TestSortingHashSet() 
    { 
     var sorted = _myHash.OrderBy(s => s.Price); 
    } 



    static void TestList() 
    { 
     var test = _searchResults.Items; 

     _myList = (from x in test 
        select new SearchResults 
           { 
            Ref = x.Ref, 
            Price = x.StandardPrice 
           }).ToList(); 
    } 

    static void TestSortingList() 
    { 
     var sorted = _myList.OrderBy(s => s.Price); 
    } 

    static void TestIQueriable() 
    { 
     var test = _searchResults.Items; 

     _myIQuery = (from x in test 
        select new SearchResults 
           { 
            Ref = x.Ref, 
            Price = x.StandardPrice 
           }).AsQueryable(); 

    } 

    static void TestSortableIQueriable() 
    { 
     var sorted = _myIQuery.OrderBy(s => s.Price); 
    } 

} 

===直接輸出===

- Hash Test 
Average Running Time: 0.154; Total Time: 1540 
- Hash Sort Test 
Average Running Time: 0.0003; Total Time: 3 
- List Test 
Average Running Time: 0.0601; Total Time: 601 
- List Sort Test 
Average Running Time: 0.0002; Total Time: 2 
- iquery Test 
Average Running Time: 0.0003; Total Time: 3 
- iquery Sort Test 
Average Running Time: 0.0399; Total Time: 399 
- IEnum Test 
Average Running Time: 0.0002; Total Time: 2 
- IEnum Sort Test 
Average Running Time: 0.0001; Total Time: 1 
Press any key to continue . . . 

顯然時間會基於什麼我的機器在當時做,你通常可以根據差異的大小作出一些判斷,但是作爲「答案」表明它以同樣的方式判斷IQueryable是不公平的。

+0

看看'IEnumerable' vs'IList'上的表現會很有意思 – 2010-05-25 22:59:32

+0

加到底部 – 2010-05-25 23:29:12

回答

2

我認爲IQueryable推遲創建,直到執行排序,IList預先創建並執行排序。

就像IList一樣,HashSet的創作並沒有延期,因此成本很高。

因此,最早的HashSetIList必須創建,這需要花費時間記錄。然後你記錄它們的排序可能可以忽略不計。 IQueryable推遲創建時間,直到你做了排序,所以創建和排序都發生在排序的時間。對於IQueryable來說,這種排序並沒有真正花費更長的時間,因爲創建是在您的測試中同時發生的。我會懷疑所有3種時差都可以忽略不計。

我認爲兩種方法都可以使用,這取決於您希望在IQueryable的情況下如何使用或擴展輸出。

+0

謝謝MSDN的描述不太好。 http://msdn.microsoft.com/en-us/library/bb397727.aspx – 2010-05-25 23:01:08