मुझे फ़ाइल से पार्स की गई दो सूचियों में पूर्ण बाहरी शामिल होने की आवश्यकता है, जहां प्रत्येक सूची में> 14 मिलियन प्रविष्टियां हैं। मेरा पहला विचार System.Linq का उपयोग करके एक सरल समाधान का उपयोग करना था

type AccountingData =
    { AccountingId: AccountingId
      Year: int
      Month: int
      Value: decimal }

let combine xs ys =
    let withDefaults (xs: AccountingData seq) (ys: AccountingData seq) =
        query {
            for x in xs do
            leftOuterJoin y in ys on (x.AccountingId = y.AccountingId) into g
            for y in g.DefaultIfEmpty() do
            select (
                if obj.ReferenceEquals(null, y) then
                    x, { x with Value = 0m }
                else
                    x, y
            )
        }
    Enumerable.Union
        (withDefaults xs ys,
         withDefaults ys xs |> Seq.map Tuple.swap)

let combined = combine xs ys

लेकिन यह इतने बड़े डेटा सेट के लिए अच्छी तरह से काम नहीं करता है और यह बेहद धीमा है। शायद यह एक पूंछ पुनरावर्ती समारोह का उपयोग करके फिर से लिखा जा सकता है? कैसे?

f#
0
Daniel 16 जून 2020, 15:20

1 उत्तर

सबसे बढ़िया उत्तर

यदि आपको ऐसे डेटा को संसाधित करने की आवश्यकता है जो स्मृति में आसानी से संभालने के लिए बहुत बड़ा है (विशेषकर यदि आपको जुड़ने की आवश्यकता है), तो डेटाबेस का उपयोग करना आसान हो सकता है। हालांकि, इस मामले में, मुझे लगता है कि आपको डेटाबेस के बिना वह करने में सक्षम होना चाहिए जो आपको चाहिए।

सबसे आसान तरीका जो काफी कुशल होना चाहिए, वह यह होगा कि एक सामान्य Dictionary<K, V> को लुकअप टेबल के रूप में इस्तेमाल किया जाए, इसे ys के मानों के साथ पॉप्युलेट किया जाए और फिर प्रत्येक x के लिए एक मिलान मान ज्ञात किया जाए। कुछ इस तरह:

let withDefaults (xs: AccountingData seq) (ys: AccountingData seq) =
  // Create a lookup for finding 'ys' by accounting Id
  let ylookup = Dictionary<_, _>()
  for y in ys do ylookup.Add(y.AccountingId, y)
  seq { 
    // Find a corresponding 'y' or default for each 'x'
    for x in xs do
      match ylookup.TryGetValue(x.AccountingId) with
      | true, y -> x, y
      | false, _ -> x, { x with Value = 0m } }

यह भी सोचने लायक है कि क्या आप डेटा को एक आलसी अनुक्रम (यानी seq<T>) के रूप में संग्रहीत करना चाहते हैं या क्या कुछ और बेहतर होगा - एक आलसी अनुक्रम के कुछ अच्छे लाभ हैं, लेकिन यह आसानी से ऐसी स्थिति का कारण बन सकता है जहाँ आप दुर्घटना से कई बार कोड फिर से चल रहे हैं।

2
Tomas Petricek 16 जून 2020, 13:03