none
Group及集合傳遞效率 RRS feed

  • 問題

  • 大家好:  

              我有一個名為cfp的list , 然後透過一個linq查詢出p3 , p3是cfp以item為group , group後的cnt必須大於等於10 , (Group pp3 By k.Item Into gg = Sum(k.Cnt)  Where gg >= 10) , 這部份並沒有問題 , 我的問題在於將p3以ByRef傳至XFP副程式 , 然後判斷p3中是否存在"111"這一項 , 這一段程式如下 , 但我發現這樣的傳遞及判斷方式程式效能很低 , 實在想不出那裡有問題 , 看大家可否給我一些意見 , 先謝謝所有回應者.

     cfp結構及資料如下:

    1   "111"   5   "1 2 3 4"

    2   "222"   3   "4 3 2 1"

    3   "111"   6   "5 6 7 8"

    4   "333"   7   "3 3 3 9"

    5   "222"   8   "5 7 8 9"

    ---------------------------------------------------

            Dim cfp As List(Of Q_fp) = New List(Of Q_fp)
                 ............

                    Dim p3 = From k In cfp _                  ' p3=111及222
                            Group pp3 By k.Item Into gg = Sum(k.Cnt) _
                            Where gg >= 10 _

                        XFP(p3,  n.Item.ToString)

    ---------------------------------------------------

     Function XFP(ByRef p3,  ByVal item_name)

                p_list = Split("000 111 222"," ")

                     q_ans = False

                    For Each nn In p3

                        If nn.item = P_list(1) Then        ' p_list(1) = "111"
                            q_ans = True
                            Exit For
                        End If

                    Next

                    If q_ans = True Then

    2012年7月24日 上午 05:52

所有回覆

  • ... 沒有任何命名規則嗎?

    程式碼這裡看不懂,那邊無法理解....


    學習不是查個 Google 套個書上的範例就算了,而是去熟悉了解每個程式碼背後的意義,否則就算學個幾百年,它也不會是你的。
    =================================
    小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
    雲端學堂Facebook: http://www.facebook.com/studyazure

    2012年7月24日 上午 10:23
    版主
  • 提供一個建議。做 grouping 的代價是很大的, 尤其是來源數量龐大又未建立索引的時候。依你所述, 如果你只是要找 "111" 這個編號, 那麼你倒不如使用 linear search, 也就是使用 for 或 foreach 迴圈來找 (也就是不使用 grouping), 這樣就能把效能從接近 O(N^2) 提升到 O(N)。


    2012年7月24日 上午 11:49
  • 謝謝Johnny.net的回應 , 我在測試過程中也寫過用for 迴圈取代linq的這一部份 , 但程式很冗長 , 而且其效能理論上會隨著搜尋累計的項目而增加 , 也就是johnny所說的O(n) , 我不曉得是否是自己程式寫的不好 , 實際上我自己寫的程式效能並沒有使用linq做grouping來的好 , 至於grouping的時間複雜度為O(n^2)與否 , 我並不知道 , 不曉得Johnny是否有相關參考資料 . 這是很值得再了解的.

    但原始發問的問題並不在linq這一部份 , 而是將linq查詢出來的集合 (或object)p3 傳送給副程式這一部份 , 我發現如果傳給副程式 , 當我打p3.時 , Intelligence並不會自動出現 item的提示  , 但是不使用副程式則可以 , 所以我懷疑是傳遞參數的問題 . 這樣的程式呼叫方式有錯嗎? 還是要加上  "as ... " , 如果是" ..." 應該是什麼?

     XFP(p3,  n.Item.ToString)

     Function XFP(ByRef p3,  ByVal item_name)

    2012年7月24日 下午 01:01
  • 你沒給型別
    2012年7月24日 下午 01:37
  • 我建議你花點時間看看我的簽名檔中最後兩個連結, 那麼或許你多少可以體會我們回答者所面對的處境, 而你的問題也能問得比較有條理。

    其次, 你在原始發問中提到效能的問題, 但在第二個問題中又說不是 linq 這一部份... 基本上, 我認為這是互相矛盾的。我建議你既然使用了 LINQ, 你最好能多花一點時間仔細把它研究一下。LINQ 指令並不會在宣告的地方執行。它會在你引用其結果時才真的去執行, 也就是當程式一進入 For Each nn In p3 這一行時才被執行。

    接著, 由於你並未明確指出你的真正需求為何, 所以我才建議你使用 linear search 方式來處理。我不是提到「如果你只是要找 "111" 這個編號」? 我在你的程式中並沒有看到你有沒有處理 "111" 以外的 entries, 所以才這麼問。如果你真的只需要處理 "111" 這一項, 那麼你就不應該使用 grouping, 因為它會連  "000", "222", "333".... 通通都去找。我也不知道 LINQ 內部怎麼做 grouping, 但是學理上我們都採用 worst case 來衡量效能, 所以它最壞就是 O(N^2)。但是實際上 .Net 內部可能採用比較聰明的 algorithm, 例如以空間換取時間的做法, 讓它效能比較優於 O(N^2)。問題是, 如果你原來就沒打算用到 "000", "222"... 等等, 那麼你去 group 它就沒什麼道理了。

    當然, 如果你除了 "111", 還需要再處理 "000", "222" 等等, 那麼你還是得使用 grouping。那麼效能的問題將無可避免地隨著你的資料量愈大而愈差。不過, 我並不認為那是因為參數傳遞方式所引起; 或許你可以試試不使用函式來處理以進行驗證。


    2012年7月24日 下午 04:09