2012-10-29 8 views
24

विंडोज 7, इंटेल कोर i3, 64 बिट, रैम 4GB, 2.27 गीगा
.नेट फ्रेमवर्क 4,0
थ्रेड और कार्य के बीच प्रदर्शन में इतना अंतर क्यों है?

मैं है निम्नलिखित कोड:

static void Main(string[] args) 
{ 
    var timer = new Stopwatch(); 
    timer.Start(); 

    for (int i = 0; i < 0xFFF; ++i) 
    { 
     // I use one of the following line at time 
     Task.Factory.StartNew(() => { }); 
     new Thread(() => { }).Start(); 
    } 

    timer.Stop(); 

    Console.WriteLine(timer.Elapsed.TotalSeconds); 
    Console.ReadLine(); 
} 

अगर मैं टास्क का उपयोग उत्पादन हमेशा होता है 0.01 सेकंड, लेकिन यदि मैं थ्रेड का उपयोग करता हूं तो आउटपुट हमेशा 40 सेकंड से अधिक होता है!
यह कैसे संभव है? इतना अंतर क्यों?

+15

एक एक कतार .. आपको लगता है कि के अलावा और कुछ नहीं कर रहे हैं को मापने में 4096 सूत्र, अन्य कतारों 4096 कार्य शुरू होता है। प्वाइंटलेस .. –

उत्तर

30

दोनों समान नहीं हैं।

जब आप Task.Factory.StartNew का उपयोग करते हैं, तो आप ThreadPool पर चलाने के लिए कोई कार्य निर्धारित कर रहे हैं। जब आप एक नया Thread बनाते हैं, तो आपको एक नया धागा बनाना और शुरू करना होगा।

पहले मामले में, धागे पहले ही बनाए गए हैं और पुन: उपयोग। इससे कार्यों को शेड्यूल करने का ओवरहेड बहुत कम हो जाता है, क्योंकि धागे को प्रत्येक पुनरावृत्ति को नहीं बनाया जाना चाहिए।

ध्यान दें कि व्यवहार समान नहीं है, हालांकि। एक अलग थ्रेड बनाते समय, प्रत्येक कार्य को अपना धागा मिल रहा है। वे सभी तुरंत शुरू हो जाएंगे। Task.Factory.StartNew का उपयोग करते समय, उन्हें ThreadPool पर चलाने के लिए शेड्यूलर में रखा जाता है, जो (संभावित रूप से) समवर्ती धागे की संख्या को सीमित कर देगा। यह आमतौर पर एक अच्छी बात है, क्योंकि यह होने से अतिप्रवाह रोकता है।

+0

इसलिए, यदि मैं कार्य का उपयोग करता हूं तो यह संभव है कि यह निर्दिष्ट प्रतिनिधि को एक समय में चलाए; यानी जब पिछला पूरा हो जाता है तो कार्य वर्ग अगले से शुरू होता है? – Nick

+0

[टास्क। कंटिन्यू विथ] (http://msdn.microsoft.com/en-us/library/dd235663.aspx): 'var t = Task.Factory.StartNew (...)। जारी रखें (...)' । – user7116

+0

@ निक आप निरंतरता का उपयोग कर सकते हैं, या, यदि आप ब्लॉक करना चाहते हैं, तो 'कार्य'/'कार्य ' पर '.Wait() 'या' Result' पर कॉल करें। ऐसा कहा जा रहा है कि, यदि आप वस्तुओं * को क्रमशः * संसाधित करना चाहते हैं, तो आप 'ब्लॉकिंग कोलेक्शन ' को देखना चाहेंगे और इसके बजाय निर्माता/उपभोक्ता परिदृश्य तैयार कर सकते हैं। –

0

Task.Factory.StartNew() तुरंत कार्य शुरू नहीं करता है, यह केवल इसे शेड्यूल करता है, इसलिए एक कार्य शेड्यूल इसे थोड़ी देर बाद शुरू करने में सक्षम होगा (उपलब्ध थ्रेड/कार्यों की संख्या पर निर्भर करता है)।

एमएसडीएन ने कहा कि Thread.Start() ऑपरेटिंग सिस्टम इसे निष्पादन के लिए शेड्यूल कर सकता है, ओएस के साथ इंटरैक्शन .NET Framework के टास्कशेड्यूलर की तुलना में बहुत धीमी है लेकिन ऐसी डिग्री में नहीं है।

और अपने उदाहरण पर वापस 0xFFF == 4095, तो आप 40 9 5 धागे शेड्यूल कर रहे हैं और इसमें 40 सेकंड लगते हैं। एक सेकंड में 102 धागे एक बहुत अच्छा समय है! :)

4

हर बार जब आप Task शुरू करते हैं तो यह कई धागे द्वारा परोसा जाने वाला पूल में जाता है, जिनमें से कई पूर्व-निर्मित हो सकते हैं। पूल में M:N कार्यों के अनुपात में धागे के अनुपात हैं।

हर बार जब आप Thread शुरू करते हैं तो यह एक नया थ्रेड बनाता है और थ्रेड सृजन से जुड़े सभी ओवरहेड बनाता है। चूंकि आप स्पष्ट रूप से धागे बना रहे हैं, धागे का 1: 1 अनुपात है।

कार्यों के धागे के अनुपात के करीब 1 तक पहुंचता है, "धीमा" कार्य स्टार्टअप इसे ले जाएगा। हकीकत में, ThreadPool सुनिश्चित करता है अनुपात की तुलना में 1.

0

Task.Factory.StartNew कॉलिंग जरूरी एक नया धागा पैदा नहीं करता बहुत अधिक रहता है, वे कितने कोर आदि मशीन है कि कोड चल रहा है है पर आधारित TaskScheduler द्वारा प्रबंधित कर रहे हैं।

यदि आप शेड्यूल करते हैं (Task.Factory.StartNew पर कॉल करके) समसामयिक रूप से चलाने के मुकाबले अधिक कार्य करते हैं, तो उन्हें कतारबद्ध और चलाया जाएगा क्योंकि अधिक संसाधन उपलब्ध हो जाएंगे।

1

आपको अपने परीक्षण के साथ कोई समस्या है, जिसमें आप प्रत्येक थ्रेड/कार्य को समाप्त करने की प्रतीक्षा नहीं करते हैं।

कार्य एक कतार का उपयोग करता है, इसलिए थ्रेड से कार्य बनाने के लिए यह बहुत तेज है।

मैं शर्त लगाऊंगा कि यदि आप कार्य/थ्रेड को समाप्त करने के लिए इंतजार कर रहे हैं, तो एक कार्य का उपयोग करना तेज़ है। एक थ्रेड बनाने और फिर नष्ट करने का ऊपरी भाग ऊंचा है। यही कारण है कि कार्य। कारखाना बनाया गया था!

0

नए धागे बनाना धीमा है, लेकिन धीमा नहीं है। निक ने ~ 10ms/धागा की सूचना दी। सबसे अधिक संभावना यह विजुअल स्टूडियो डीबगर के तहत हुआ। मुझे विजुअल स्टूडियो डीबगर के तहत ~ 3.9ms प्रति नए थ्रेड मिल रहा है। मुझे डीबगर के बिना ~ 0.15ms प्रति नया धागा मिल रहा है।

http://dennisgorelik.livejournal.com/125269.html?thread=2238805#t2238805

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