c# - सी#में primes की गणना करने का सबसे तेज़ तरीका है?




.net performance (6)

समांतरता एक तरफ, आप प्रत्येक पुनरावृत्ति पर sqrt (तक) की गणना नहीं करना चाहते। आप 2, 3 और 5 के गुणकों को भी मान सकते हैं और केवल {1,5} में एन% 6 या {1,7,11,13,17,19,23,29} में एन% 30 की गणना कर सकते हैं।

आप फैक्टरिंग एल्गोरिथ्म को बहुत आसानी से समांतर करने में सक्षम होना चाहिए, क्योंकि एनटी चरण केवल sqrt (n) वें परिणाम पर निर्भर करता है, इसलिए कुछ समय बाद कोई भी संघर्ष नहीं होगा। लेकिन यह एक अच्छा एल्गोरिथ्म नहीं है, क्योंकि इसके बहुत से विभाजन की आवश्यकता होती है।

आप चलनी एल्गोरिदम को समानांतर करने में सक्षम होना चाहिए, यदि आपके पास लेखक के काम के पैकेट हैं जो पढ़ने से पहले पूरा करने की गारंटी है। अधिकतर लेखकों को पाठक के साथ संघर्ष नहीं करना चाहिए - कम से कम एक बार आपने कुछ प्रविष्टियां पूरी कर ली हैं, उन्हें पाठक से कम से कम एन काम करना चाहिए, इसलिए आपको केवल एक सिंक्रनाइज़ किए गए पढ़ने की आवश्यकता होती है (जब एन पिछले सिंक्रनाइज़ किए गए पढ़ने से अधिक हो जाता है मूल्य)। आपको किसी भी संख्या के लेखक धागे में बुल सरणी को सिंक्रनाइज़ करने की आवश्यकता नहीं है, क्योंकि लिखने के संघर्ष उत्पन्न नहीं होते हैं (सबसे खराब में, एक से अधिक धागे उसी स्थान पर सही लिखेंगे)।

मुख्य मुद्दा यह सुनिश्चित करने के लिए होगा कि किसी भी कर्मचारी को लिखने के लिए प्रतीक्षा करनी पड़ी है। सी ++ में आप उस कार्यकर्ता को स्विच करने के लिए एक तुलना और सेट का उपयोग करेंगे, जो कि किसी भी समय के लिए प्रतीक्षा कर रहे हैं। मैं एक सी # wonk नहीं हूँ, इसलिए यह नहीं पता कि यह भाषा कैसे करें, लेकिन Win32 InterlockedCompareExchange फ़ंक्शन उपलब्ध होना चाहिए।

आप एक अभिनेता आधारित दृष्टिकोण की कोशिश भी कर सकते हैं, इस तरह से आप निम्नतम मूल्यों के साथ काम करने वाले अभिनेताओं को समय-समय पर शेड्यूल कर सकते हैं, जो गारंटी देना आसान हो सकता है कि आप चलनी के वैध हिस्सों को पढ़ रहे हैं, बिना प्रत्येक वेतन पर बस को लॉक करना एन

किसी भी तरह से, आपको यह सुनिश्चित करना है कि आप सभी श्रमिकों को इसे पढ़ने से पहले प्रवेश एन से ऊपर मिला, और यह करने की लागत वह है जहां समानांतर और सीरियल के बीच व्यापार बंद किया जाता है।

मेरे पास वास्तव में मेरे प्रश्न का उत्तर है लेकिन यह समानांतर नहीं है इसलिए मैं एल्गोरिथम को सुधारने के तरीकों में दिलचस्पी ले रहा हूं। वैसे भी कुछ लोगों के लिए यह उपयोगी हो सकता है

int Until = 20000000;
BitArray PrimeBits = new BitArray(Until, true);

/*
 * Sieve of Eratosthenes
 * PrimeBits is a simple BitArray where all bit is an integer
 * and we mark composite numbers as false
 */

PrimeBits.Set(0, false); // You don't actually need this, just
PrimeBits.Set(1, false); // remindig you that 2 is the smallest prime

for (int P = 2; P < (int)Math.Sqrt(Until) + 1; P++)
    if (PrimeBits.Get(P))
        // These are going to be the multiples of P if it is a prime
        for (int PMultiply = P * 2; PMultiply < Until; PMultiply += P)
            PrimeBits.Set(PMultiply, false);

// We use this to store the actual prime numbers
List<int> Primes = new List<int>();

for (int i = 2; i < Until; i++)
    if (PrimeBits.Get(i))
        Primes.Add(i);

हो सकता है कि मैं एक साथ कई BitArray और बिटअरे। और () का उपयोग कर सकता हूं?


आप दोगुनी लिंक वाली सूची के साथ अपनी बिट सरणी को क्रॉस-रेफ्रेंस करके कुछ समय बचा सकते हैं, ताकि आप अगले प्रधानमण्डल को और अधिक तेज़ी से आगे बढ़ा सकें।

इसके अलावा, बाद में कंपोजिट को खत्म करने के बाद पहली बार एक नया प्राइम पिक्स किया जाता है - पी के पहले कंपोजिट मल्टीपी पी * पी होगा, क्योंकि इससे पहले ही सब कुछ समाप्त हो चुका है। वास्तव में, आपको केवल सूची में उसके बाद शेष सभी शेष संभावित प्राइम्स के साथ ही गुणा करने की आवश्यकता होती है, जैसे ही आपका उत्पाद रेंज (जब तक बड़ा हो) से बाहर हो जाता है।

वहाँ भी कुछ अच्छा विश्लेषणात्मक एल्गोरिदम हैं, जैसे कि मिलर-आरबिन टेस्ट। विकिपीडिया पृष्ठ एक अच्छी शुरुआत है


प्रोफ़ाइल के बिना हम यह नहीं बता सकते कि कार्यक्रम के किस बिट को अनुकूलन की आवश्यकता है।

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

एक दर्जन या उससे अधिक निर्देशों के साथ एक लूप की रूपरेखा करते हुए आमतौर पर इसके लायक नहीं होते हैं - प्रोफाइलर का ऊपरी भाग लूप बॉडी के मुकाबले महत्वपूर्ण होता है, और एक पाश को सुधारने के एकमात्र तरीके हैं जो कम पुनरावृत्त करने के लिए अल्गोरिदम को बदलना है । इसलिए आईएमई, एक बार जब आप किसी भी महंगे कार्य का सफाया कर चुके हैं और सरल कोड की कुछ पंक्तियों का ज्ञात लक्ष्य प्राप्त करते हैं, तो आप कथन स्तर से कोड को सुधारने की कोशिश करते हुए एल्गोरिदम को बदलने और एक एंड-टू-एंड रन के समय से बेहतर होते हैं रूपरेखा।


आपको एल्गोरिदम के संभावित परिवर्तन पर भी विचार करना चाहिए।

मान लें कि ये तत्वों को आपकी सूची में बस जोड़ना सस्ता हो सकता है, जैसा कि आप पाते हैं

शायद आपकी सूची के लिए जगह प्रीलोकेट करना, इसे सस्ता बनाना / पॉप्युलेट करना होगा।


क्या आप नई प्राथमिकताओं को ढूंढने की कोशिश कर रहे हैं? यह बेवकूफ लग सकता है, लेकिन आप ज्ञात प्राइम्स के साथ किसी प्रकार की डेटा संरचना को लोड करने में सक्षम हो सकते हैं। मुझे यकीन है कि किसी के पास सूची है नए नंबरों की गणना करने वाले मौजूदा नंबरों को ढूंढने में यह बहुत आसान समस्या हो सकती है

आप बहु-कोर सिस्टम का लाभ लेने के लिए अपने मौजूदा कोड को बहु-थ्रेडेड बनाने के लिए माइक्रोसॉफ्ट्स समानांतर FX लाइब्रेरी पर भी देख सकते हैं। न्यूनतम कोड परिवर्तनों के साथ आप बहु-थ्रेडेड लूप के लिए कर सकते हैं।


    void PrimeNumber(long number)
    {
        bool IsprimeNumber = true;
        long  value = Convert.ToInt32(Math.Sqrt(number));
        if (number % 2 == 0)
        {
            IsprimeNumber = false;
            MessageBox.Show("No It is not a Prime NUmber");
            return;
        }
        for (long i = 3; i <= value; i=i+2)
        {             
           if (number % i == 0)
            {

                MessageBox.Show("It is divisible by" + i);
                IsprimeNumber = false;
                break;
            }

        }
        if (IsprimeNumber)
        {
            MessageBox.Show("Yes Prime NUmber");
        }
        else
        {
            MessageBox.Show("No It is not a Prime NUmber");
        }
    }




bitarray