2011-03-04 10 views
6

सारांश स्वाभाविक तेजी से होता है: मैं एक साधारण plinq (समांतर Linq) प्रश्न के System.Threading.Tasks.Parallel.ForEach और समवर्ती डेटा संरचना से बदल दिया है। गति अद्भुत थी।PLinq से System.Threading.Tasks.Parallel.ForEach

तो समानांतर से स्वाभाविक रूप से तेज़ है। फॉरएच? या यह कार्य के लिए विशिष्ट है।

// Original Code 
// concurrent dictionary to store results 
var resultDict = new ConcurrentDictionary<string, MyResultType>(); 

Parallel.ForEach(items, item => 
     { 
      resultDict.TryAdd(item.Name, PerformWork(source)); 
     }); 


// new code 

var results = 
      items 
      .AsParallel() 
      .Select(item => new { item.Name, queryResult = PerformWork(item) }) 
      .ToDictionary(kv => kv.SourceName, kv => kv.queryResult); 

नोट्स: प्रत्येक कार्य (PerformWork) अब 0 और 200 के बीच एमएस चलाता है। इसे अनुकूलित करने से पहले इसे अधिक समय लगता था। यही कारण है कि मैं मुट्ठी जगह में कार्य। समानांतर पुस्तकालय का उपयोग कर रहा था। तो मैं कुल समय 2 सेकंड से 100-200 एमएस तक चला गया, कुल मिलाकर एक ही काम कर रहा था, बस विभिन्न तरीकों से। (वाह LINQ और plinq भयानक कर रहे हैं!)

प्रश्न:

  1. गति बनाम Parallel.ForEach plinq का उपयोग कर की वजह से है?
  2. क्या यह इसके बजाय समवर्ती डेटा संरचना (ConcurrentDictionary) को हटाने के बजाय है? (क्योंकि इसे धागे को सिंक्रनाइज़ करने की आवश्यकता नहीं है)।
  3. इस related question

PLINQ जबकि से जवाब के आधार पर मोटे तौर पर कोई दुष्प्रभाव के साथ प्रोग्रामिंग का एक कार्यात्मक शैली पर आधारित है, दुष्प्रभाव ठीक कर रहे हैं क्या TPL के लिए है। यदि आप समानांतर में चीजों को खोजने/चुनने के विरोध में वास्तव में समानांतर में काम करना चाहते हैं, तो आप टीपीएल का उपयोग करते हैं।

क्या मुझे लगता है कि मेरा पैटर्न मूल रूप से कार्यात्मक है (इनपुट देने से उत्परिवर्तन के बिना नए आउटपुट उत्पन्न होते हैं), कि प्लिनक उपयोग करने के लिए सही तकनीक है?

मैं सत्यापन की तलाश में हूं कि मेरी धारणाएं सही हैं, या एक संकेत है कि मुझे कुछ याद आ रही है।

+0

आपके "आइटम" चर का डेटा प्रकार और इसमें कितने आइटम हैं? –

उत्तर

2

आपके नमूने में दी गई सीमित जानकारी के आधार पर (मैंने ओपी पर एक टिप्पणी में अधिक जानकारी के लिए कहा), मुझे लगता है कि आप विभाजन वाले एल्गोरिदम के कारण अंतर देख रहे हैं। आपको इस ब्लॉग पोस्ट में Chunk Partitioning vs. Range Partitioning पर पढ़ना चाहिए जहां वह चर्चा करता है कि वे कैसे भिन्न होते हैं और किस प्रकार के काम के लिए वे सबसे उपयुक्त हो सकते हैं। अत्यधिक अनुशंसा करते हैं कि आप उस ब्लॉग आलेख के साथ-साथ this one पढ़ लें जो कि दो अन्य प्रकार के विभाजन के साथ उन दो प्रकारों पर थोड़ा अधिक विस्तार में जाता है, जिनका उपयोग आपके नमूने पर लागू नहीं हो सकता है, साथ ही कुछ दृश्य सहायक उपकरण को बेहतर तरीके से देना विभाजन को समझें। अंत में, here's yet another blog post जो कार्य विभाजन पर चर्चा करता है और डिफ़ॉल्ट विभाजन एल्गोरिदम आपके विशेष वर्कलोड के लिए समझ में नहीं आता है, तो यह आपको कैसे प्रभावित कर सकता है।वह पोस्ट वास्तव में एक महान कार्यक्रम को संदर्भित करता है जो आपको विभाजन पर प्रकाशकों को देखने में मदद करता है जो a set of parallel samples from the PFX team का हिस्सा है।

4

Parallel.ForEach और PLINQ के बीच एक निश्चित तुलना करने के लिए इन 2 कोड नमूने का उपयोग करना संभव नहीं है। कोड नमूने बस बहुत अलग हैं।

पहला आइटम जो मुझ पर कूदता है वह पहला नमूना ConcurrentDictionary का उपयोग करता है और दूसरा Dictionary का उपयोग करता है। इन दो प्रकारों में बहुत अलग उपयोग और प्रदर्शन विशेषताएं हैं। दो तकनीकों के बीच सटीक तुलना प्राप्त करने के लिए आपको यहां प्रकारों के साथ संगत होने की आवश्यकता है।

+0

समांतर के साथ नियमित जेनेरिक शब्दकोश लोड करना संभव कैसे होगा। फॉरएच? –

+0

@ क्रिस मुझे यकीन नहीं है कि यह किसी प्रकार के लॉकिंग के बिना संभव है। – JaredPar

+0

@JarePar दाएं। यह मेरे प्रश्न का संदर्भ है (हालांकि शायद अच्छी तरह से नहीं कहा गया है)। मैं समानांतर में कुछ कैसे करूं और एक शब्दकोश वापस कर सकता हूं। इस मामले में, प्लिनक रास्ता तेज था। क्या यह समस्याओं की एक कक्षा के लिए सामान्य है या बस ConcurrentDictionary के साथ एक quirk है। –

संबंधित मुद्दे