जावा स्ट्रिंग से सभी गैर-मुद्रण योग्य वर्णों को छीनने का सबसे तेज़ तरीका


82

Stringजावा में सभी गैर-मुद्रण योग्य वर्णों को छीनने का सबसे तेज़ तरीका क्या है ?

अब तक मैंने 138-बाइट, 131-कैरेक्टर स्ट्रिंग पर कोशिश की है और मापा है:

  • स्ट्रिंग की replaceAll()- सबसे धीमी विधि
    • 517009 परिणाम / सेकंड
  • एक पैटर्न को रोकें, फिर मिलानकर्ता का उपयोग करें replaceAll()
    • 637836 परिणाम / सेकंड
  • StringBuffer का उपयोग करें, codepointAt()एक-एक करके कोडपॉइंट प्राप्त करें और StringBuffer का उपयोग करें
    • 711946 परिणाम / सेकंड
  • StringBuffer का उपयोग करें, charAt()एक-एक करके chars प्राप्त करें और StringBuffer का उपयोग करें
    • 1052964 परिणाम / सेकंड
  • एक char[]बफर को प्रीचॉक करें , charAt()एक-एक करके चार्ट प्राप्त करें और इस बफर को भरें, फिर वापस स्ट्रिंग में परिवर्तित करें
    • 2022653 परिणाम / सेकंड
  • Preallocate 2 char[]बफ़र्स - पुराने और नए, एक ही समय में मौजूदा स्ट्रिंग के लिए सभी वर्ण प्राप्त करें getChars(), एक- एक करके पुराने बफर पर पुनरावृति करें और नए बफर भरें, फिर नए बफर को स्ट्रिंग में बदलें - मेरा अपना सबसे तेज़ संस्करण
    • 2502502 परिणाम / सेकंड
  • 2 बफ़र्स के साथ एक ही सामान - केवल उपयोग byte[], getBytes()और "utf-8" के रूप में एन्कोडिंग निर्दिष्ट करना
    • 857485 परिणाम / सेकंड
  • 2 byte[]बफ़र्स के साथ सामान , लेकिन एन्कोडिंग को एक स्थिर के रूप में निर्दिष्ट करनाCharset.forName("utf-8")
    • 791076 परिणाम / सेकंड
  • 2 byte[]बफ़र्स के साथ समान सामान , लेकिन एन्कोडिंग को 1-बाइट स्थानीय एन्कोडिंग के रूप में निर्दिष्ट करना (बमुश्किल एक समझदार चीज़ है)
    • 370164 परिणाम / सेकंड

मेरी सबसे अच्छी कोशिश निम्नलिखित थी:

    char[] oldChars = new char[s.length()];
    s.getChars(0, s.length(), oldChars, 0);
    char[] newChars = new char[s.length()];
    int newLen = 0;
    for (int j = 0; j < s.length(); j++) {
        char ch = oldChars[j];
        if (ch >= ' ') {
            newChars[newLen] = ch;
            newLen++;
        }
    }
    s = new String(newChars, 0, newLen);

इसे और भी तेज़ बनाने के बारे में कोई विचार?

एक बहुत ही अजीब सवाल का जवाब देने के लिए बोनस अंक: "यूटीएफ -8" चारसेट नाम का उपयोग करके पूर्व-आवंटित स्टैटिक कॉस्ट का उपयोग करने से बेहतर प्रदर्शन सीधे Charset.forName("utf-8")क्यों मिलता है?

अपडेट करें

  • शाफ़्ट सनकी से सुझाव प्रभावशाली 3105590 परिणाम / सेकंड प्रदर्शन, एक + 24% सुधार!
  • एड स्टाब से सुझाव अभी तक एक और सुधार - 3471017 परिणाम / सेकंड, पिछले सर्वश्रेष्ठ से अधिक 12%।

अपडेट २

मैंने सभी प्रस्तावित समाधानों और इसके क्रॉस-म्यूटेशन को इकट्ठा करने की पूरी कोशिश की है और इसे जीथब में एक छोटे बेंचमार्किंग फ्रेमवर्क के रूप में प्रकाशित किया है । वर्तमान में यह 17 एल्गोरिदम को स्पोर्ट करता है। उनमें से एक "विशेष" है - Voo1 एल्गोरिथ्म ( एसओ उपयोगकर्ता वू द्वारा प्रदान किया गया ) जटिल प्रतिबिंब चाल को नियोजित करता है जिससे तारकीय गति प्राप्त होती है, लेकिन यह जेवीएम स्ट्रिंग्स की स्थिति को गड़बड़ कर देता है, इस प्रकार इसे अलग से बेंचमार्क किया जाता है।

अपने बॉक्स पर परिणाम निर्धारित करने के लिए इसका स्वागत करते हैं और इसे चलाने के लिए आपका स्वागत है। यहां मेरे द्वारा प्राप्त किए गए परिणामों का सारांश है। यह चश्मा है:

  • डेबियन का किनारा
  • लिनक्स 2.6.39-2-amd64 (x86_64)
  • एक पैकेज से स्थापित जावा sun-java6-jdk-6.24-1, जेवीएम खुद की पहचान करता है
    • जावा (TM) एसई रनटाइम एनवायरनमेंट (बिल्ड 1.6.0_24-b07)
    • जावा हॉटस्पॉट (टीएम) 64-बिट सर्वर वीएम (19.1-b02, मिश्रित मोड का निर्माण)

अलग-अलग एल्गोरिदम अंततः इनपुट डेटा के एक अलग सेट को देखते हुए अलग-अलग परिणाम दिखाते हैं। मैंने 3 मोड में एक बेंचमार्क चलाया है:

एक ही तार

यह मोड StringSourceएक स्थिर के रूप में वर्ग द्वारा प्रदान की गई एक ही स्ट्रिंग पर काम करता है। तसलीम है:

 ऑप्स / एस / एल्गोरिथम
──────────┼──────────────────────────────
6 535 947 1 Voo1
──────────┼──────────────────────────────
५ ३५० ४५४ c रत्चेफ्रीके २ इदसताब १ ग्रेगेट १
5 249 343 S EdStaub1
5 002 501 S EdStaub1GreyCat1
4 859 086 ray ArrayOfCharFromStringCharAt
4 295 532 c शाफ़्टफ़्रेक 1
4 045 307 │ ArrayOfCharFromArrayOfChar
2 790 178 790 रत्चेफ्रीके 2 ईडसटब 1 ग्रेकैट 2
२ ५ 2३ ३११ 3 रत्चेफ्रीके २
१ २ 1४ har५ ९ 4 स्ट्रिंगब्रुलेचर
1 138 174 ring StringBuilderCodePoint
  994 727 ray ArrayOfByteUTF8String
  918 611 O ArrayOfByteUTF8Const
  756 086 0 माचिसरैल
  598 945 8 StringReplaceAll
  460 045 0 ArrayOfByteWindows1251

चार्टेड रूप में: (स्रोत: greycat.ru )एक ही स्ट्रिंग चार्ट

एकाधिक तार, 100% तार में नियंत्रण वर्ण होते हैं

स्रोत स्ट्रिंग प्रदाता ने (0..127) वर्ण सेट का उपयोग करते हुए बहुत सारे यादृच्छिक तार उत्पन्न किए - इस प्रकार लगभग सभी तारों में कम से कम एक नियंत्रण वर्ण होता है। राउंड-रॉबिन फैशन में इस पूर्व-निर्मित सरणी से एल्गोरिदम को तार मिले।

 ऑप्स / एस / एल्गोरिथम
──────────┼──────────────────────────────
2 123 142 2 Voo1
──────────┼──────────────────────────────
1 782 214 21 EdStaub1
1 776 199 S EdStaub1GreyCat1
1 694 628 ray ArrayOfCharFromStringCharAt
1 481 481 ray ArrayOfCharFromArrayOfChar
१ ४६० ०६│ c रत्चेफ्रीके २ ईडसटब १ ग्रेगेट १
१ ४३ 1 ४३५ c रत्चेफ्रीके २ ईदसताब १ ग्रेगेट २
1 366 494 49 शाफ़्टफ़्रेक 2
१ ३४ ९ .१० 7 रत्चेफ्रीके १
  893 176 8 ArrayOfByteUTF8String
  817 127 17 ArrayOfByteUTF8Const
  778 089 B StringBuilderChar
  734 754 B StringBuilderCodePoint
  377 829 O ArrayOfByteWindows1251
  224 140 4 माचिस की दर
  211 104 1 StringReplaceAll

चार्टेड रूप में: (स्रोत: greycat.ru )एकाधिक तार, 100% एकाग्रता

एकाधिक स्ट्रिंग्स, स्ट्रिंग्स के 1% में नियंत्रण वर्ण होते हैं

पिछले की तरह ही, लेकिन नियंत्रण पात्रों के साथ केवल 1% तार उत्पन्न हुए थे - अन्य 99% [32..127] वर्ण सेट का उपयोग करके उत्पन्न किया गया था, इसलिए वे नियंत्रण वर्णों को शामिल नहीं कर सकते थे। यह सिंथेटिक लोड मेरे स्थान पर इस एल्गोरिथ्म के वास्तविक विश्व अनुप्रयोग के सबसे करीब आता है।

 ऑप्स / एस / एल्गोरिथम
──────────┼──────────────────────────────
3 711 952 oo Voo1
──────────┼──────────────────────────────
2 851 440 S EdStaub1GreyCat1
2 455 796 S EdStaub1
2 426 007 O ArrayOfCharFromStringCharAt
2 347 969 c रत्चेफ्रीके 2 ईडसटब 1 ग्रेयकट 2
२ २४२ १५२ c रत्चेफ्रीके १
2 171 553 ray ArrayOfCharFromArrayOfChar
१ ९ २२ E०E c रत्चेफ्रीक २ ईडसटब १ ग्रेगेट १
1 857 010 0 शाफ़्टफ़्रेक 2
1 023 751 ray ArrayOfByteUTF8String
  939 055 B स्ट्रिंगबर्लचर
  907 194 O ArrayOfByteUTF8Const
  841 963 B StringBuilderCodePoint
  606 465 6 माचिस की दर
  501 555 55 StringReplaceAll
  381 185 O ArrayOfByteWindows1251

चार्टेड रूप में: (स्रोत: greycat.ru )एकाधिक तार, 1% एकाग्रता

मेरे लिए यह तय करना बहुत कठिन है कि सबसे अच्छा उत्तर किसने दिया, लेकिन वास्तविक दुनिया के लिए सबसे अच्छा समाधान एड स्टब द्वारा दिया गया / प्रेरित था, मुझे लगता है कि उनके उत्तर को चिह्नित करना उचित होगा। इसमें भाग लेने वाले सभी लोगों के लिए धन्यवाद, आपका इनपुट बहुत मददगार और अमूल्य था। अपने बॉक्स पर परीक्षण सूट चलाने के लिए स्वतंत्र महसूस करें और बेहतर समाधानों का प्रस्ताव रखें (जेएनआई समाधान, किसी को भी काम कर रहे हैं?)।

संदर्भ


21
"यह प्रश्न अनुसंधान के प्रयास को दिखाता है" - हम्म ... हाँ, पास। +1
गुस्ताव बार्केफ़ोर्स

7
StringBuilderके StringBufferरूप में यह संयुक्त राष्ट्र के सिंक्रनाइज़ेशन की तुलना में मामूली रूप से तेज़ होगा , मैं सिर्फ इसका उल्लेख करता हूं क्योंकि आपने इसे टैग किया हैmicro-optimization

2
@ जेरोड रॉबर्सन: ठीक है, तो चलिए सभी रीड-ओनली फील्ड्स को फाइनल s.length()करते हैं और forलूप से बाहर भी निकालते हैं :-)
घर

3
अंतरिक्ष के नीचे के कुछ अक्षर मुद्रण योग्य हैं जैसे \tऔर \n। आपके चरित्र सेट में 127 से ऊपर के कई अक्षर गैर-मुद्रण योग्य हैं।
पीटर लॉरी

1
क्या आपने स्ट्रिंग बफर की क्षमता के साथ init किया है s.length()?
शाफ़्ट फ़्रेक

जवाबों:


11

यदि इस विधि को उस वर्ग में एम्बेड करना उचित है जिसे थ्रेड्स में साझा नहीं किया गया है, तो आप बफर का पुन: उपयोग कर सकते हैं:

char [] oldChars = new char[5];

String stripControlChars(String s)
{
    final int inputLen = s.length();
    if ( oldChars.length < inputLen )
    {
        oldChars = new char[inputLen];
    }
    s.getChars(0, inputLen, oldChars, 0);

आदि...

यह एक बड़ी जीत है - 20% या तो, जैसा कि मैं वर्तमान सर्वश्रेष्ठ मामले को समझता हूं।

यदि इसका उपयोग संभावित रूप से बड़े तारों पर किया जाना है और मेमोरी "लीक" एक चिंता का विषय है, तो एक कमजोर संदर्भ का उपयोग किया जा सकता है।


महान विचार! अब तक यह 3471017 स्ट्रिंग्स प्रति सेकंड की गिनती में लाया - यानी पिछले सबसे अच्छे संस्करण पर + 12% सुधार।
ग्रेचैट

25

1 चार सरणी का उपयोग करना थोड़ा बेहतर काम कर सकता है

int length = s.length();
char[] oldChars = new char[length];
s.getChars(0, length, oldChars, 0);
int newLen = 0;
for (int j = 0; j < length; j++) {
    char ch = oldChars[j];
    if (ch >= ' ') {
        oldChars[newLen] = ch;
        newLen++;
    }
}
s = new String(oldChars, 0, newLen);

और मैंने बार-बार कॉल करने से परहेज किया s.length();

एक और सूक्ष्म अनुकूलन जो काम कर सकता है

int length = s.length();
char[] oldChars = new char[length+1];
s.getChars(0, length, oldChars, 0);
oldChars[length]='\0';//avoiding explicit bound check in while
int newLen=-1;
while(oldChars[++newLen]>=' ');//find first non-printable,
                       // if there are none it ends on the null char I appended
for (int  j = newLen; j < length; j++) {
    char ch = oldChars[j];
    if (ch >= ' ') {
        oldChars[newLen] = ch;//the while avoids repeated overwriting here when newLen==j
        newLen++;
    }
}
s = new String(oldChars, 0, newLen);

1
धन्यवाद! आपका संस्करण 3105590 तार / सेकंड प्राप्त करता है - एक भारी सुधार!
ग्रेकट

newLen++;: पूर्वसर्ग का उपयोग करने के बारे में क्या ++newLen;? - ( ++jलूप में भी)। यहाँ एक नज़र है: stackoverflow.com/questions/1546981/…
थॉमस

finalइस एल्गोरिथ्म में जोड़ना और उपयोग करना oldChars[newLen++]( ++newLenएक त्रुटि है - पूरे स्ट्रिंग 1 से बंद हो जाएगा!) कोई औसत दर्जे का प्रदर्शन लाभ नहीं मिलता है (यानी मुझे .3 2..3% अंतर मिलता है, जो विभिन्न रनों के अंतर के बराबर हैं)
GreyCat

@ ग्रे I ने कुछ अन्य अनुकूलन के साथ एक और संस्करण बनाया
शाफ़्ट फ्रीक

2
हम्म! यह एक शानदार विचार है! मेरे उत्पादन वातावरण में ९९.९% स्ट्रिंग्स को वास्तव में स्ट्रिपिंग की आवश्यकता नहीं होगी - मैं इसे पहले char[]आवंटन को समाप्त करने और स्ट्रिंग को वापस करने के लिए आगे भी सुधार कर सकता हूं , यदि कोई स्ट्रिपिंग नहीं हुई है।
ग्रेचैट

11

वैसे मैंने अपने उपायों के अनुसार वर्तमान सर्वोत्तम विधि (उपदेश सरणी के साथ सनकी समाधान) को लगभग 30% से हराया है। कैसे? मेरी आत्मा बेचकर।

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

वैसे भी हम यहाँ जाते हैं:

    // Has to be done only once - so cache those! Prohibitively expensive otherwise
    private Field value;
    private Field offset;
    private Field count;
    private Field hash;
    {
        try {
            value = String.class.getDeclaredField("value");
            value.setAccessible(true);
            offset = String.class.getDeclaredField("offset");
            offset.setAccessible(true);
            count = String.class.getDeclaredField("count");
            count.setAccessible(true);
            hash = String.class.getDeclaredField("hash");
            hash.setAccessible(true);               
        }
        catch (NoSuchFieldException e) {
            throw new RuntimeException();
        }

    }

    @Override
    public String strip(final String old) {
        final int length = old.length();
        char[] chars = null;
        int off = 0;
        try {
            chars = (char[]) value.get(old);
            off = offset.getInt(old);
        }
        catch(IllegalArgumentException e) {
            throw new RuntimeException(e);
        }
        catch(IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        int newLen = off;
        for(int j = off; j < off + length; j++) {
            final char ch = chars[j];
            if (ch >= ' ') {
                chars[newLen] = ch;
                newLen++;
            }
        }
        if (newLen - off != length) {
            // We changed the internal state of the string, so at least
            // be friendly enough to correct it.
            try {
                count.setInt(old, newLen - off);
                // Have to recompute hash later on
                hash.setInt(old, 0);
            }
            catch(IllegalArgumentException e) {
                e.printStackTrace();
            }
            catch(IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        // Well we have to return something
        return old;
    }

मेरे परीक्षण के लिए जो पुराने संस्करण के लिए 3477148.18ops/sबनाम हो जाता है 2616120.89ops/s। मुझे यकीन है कि बीट करने का एकमात्र तरीका यह हो सकता है कि इसे सी (शायद नहीं) में लिखें या कुछ पूरी तरह से अलग दृष्टिकोण के बारे में अभी तक किसी ने भी नहीं सोचा है। हालांकि मुझे बिल्कुल यकीन नहीं है कि यदि समय अलग-अलग प्लेटफार्मों पर स्थिर है - कम से कम मेरे बॉक्स (Java7, Win7 x64) पर विश्वसनीय परिणाम पैदा करता है।


समाधान के लिए धन्यवाद, कृपया प्रश्न अपडेट देखें - मैंने अपना परीक्षण ढांचा प्रकाशित किया है और 17 एल्गोरिदम के लिए 3 परीक्षण रन परिणाम जोड़े हैं। आपका एल्गोरिथ्म हमेशा शीर्ष पर है, लेकिन यह जावा स्ट्रिंग की आंतरिक स्थिति को बदलता है, इस प्रकार "अपरिवर्तनीय स्ट्रिंग" अनुबंध => को तोड़कर वास्तविक दुनिया के अनुप्रयोग में इसका उपयोग करना बहुत कठिन होगा। टेस्ट-वार, हाँ, यह सबसे अच्छा परिणाम है, लेकिन मुझे लगता है कि मैं इसे एक अलग नामांकन के रूप में घोषित करूँगा :)
ग्रेचैट

3
@ ग्रेकैट हाँ, यह निश्चित रूप से कुछ बड़े तार जुड़ा हुआ है और ईमानदारी से मैंने बहुत ही इसे लिखा है क्योंकि मुझे पूरा यकीन है कि आपके वर्तमान सर्वोत्तम समाधान को और बेहतर बनाने के लिए कोई ध्यान देने योग्य तरीका नहीं है। ऐसी स्थितियाँ हैं जहाँ मैं निश्चित हूँ कि यह ठीक काम करेगी (इसे हटाने से पहले कोई विकल्प या आंतरिक कॉल नहीं), लेकिन ऐसा इसलिए है क्योंकि एक वर्तमान हॉटस्पॉट संस्करण के बारे में ज्ञान है (यानी जब तक यह इंटर्न स्ट्रिंग्स नहीं पढ़ेगा IO - willn ' टी विशेष रूप से उपयोगी हो)। यह उपयोगी हो सकता है अगर किसी को उन अतिरिक्त एक्स% की आवश्यकता होती है, लेकिन अन्यथा एक आधारभूत यह देखने के लिए कि आप अभी भी कितना उपयोग कर सकते हैं।)
वू

1
हालांकि मुझे समय मिलने पर जेएनआई संस्करण का प्रयास करने का प्रयास किया गया है - कभी भी इसका उपयोग नहीं किया है ताकि यह दिलचस्प हो। लेकिन मुझे पूरा यकीन है कि अतिरिक्त कॉलिंग ओवरहेड (स्ट्रिंग्स वैसे भी बहुत छोटे हैं) की वजह से यह धीमा होगा और तथ्य यह है कि जेआईटी को इस तरह के कठिन समय के कार्यों का अनुकूलन नहीं करना चाहिए। new String()यदि आपका तार नहीं बदला गया था, तो बस उपयोग न करें , लेकिन मुझे लगता है कि आपको वह पहले ही मिल गया है।
वू

मैंने पहले से ही शुद्ध सी में बिल्कुल वही काम करने की कोशिश की है - और, ठीक है, यह आपके प्रतिबिंब-आधारित संस्करण पर वास्तव में बहुत सुधार नहीं दिखाता है। C संस्करण + 5..10% तेजी से कुछ इस तरह से चलता है, वास्तव में यह बहुत अच्छा नहीं है - मुझे लगा कि यह कम से कम 1.5x-
1.7x की

2

प्रोसेसर की मात्रा के आधार पर आप कार्य को कई समानांतर उप-प्रकारों में विभाजित कर सकते हैं।


हाँ, मैंने इसके बारे में भी सोचा था, लेकिन यह मेरी स्थिति में किसी भी प्रदर्शन लाभ को प्राप्त नहीं करेगा - इस स्ट्रिपिंग एल्गोरिथ्म को पहले से ही बड़े पैमाने पर समानांतर सिस्टम में कहा जाएगा।
ग्रेकट

2
और, इसके अलावा, मैं अनुमान लगा सकता हूं कि प्रत्येक 50-100 बाइट स्ट्रिंग के प्रसंस्करण के लिए कुछ थ्रेड को बंद करना एक बहुत बड़ा ओवरकिल होगा।
ग्रेकट

हां, हर छोटी स्ट्रिंग के लिए थ्रेडिंग करना अच्छा विचार नहीं है। लेकिन लोड बैलेंसर प्रदर्शन में सुधार कर सकता है। BTW, क्या आपने StringBuer के बजाय StringBuffer के साथ प्रदर्शन का परीक्षण किया था जिसमें प्रदर्शन की कमी है क्योंकि यह सिंक्रनाइज़ है।
umbr

मेरा उत्पादन सेटअप कई अलग-अलग प्रक्रियाओं को चलाता है और जितना संभव हो उतना समानांतर सीपीयू और कोर का उपयोग करता है, इसलिए मैं StringBuilderबिना किसी मुद्दे के हर जगह स्वतंत्र रूप से उपयोग कर सकता हूं ।
GreyCat

2

मैं बहुत स्वतंत्र था और विभिन्न एल्गोरिदम के लिए एक छोटा बेंचमार्क लिखा था। यह सही नहीं है, लेकिन मैं किसी यादृच्छिक एल्गोरिथ्म पर 10000 बार न्यूनतम एल्गोरिथ्म के 1000 रन लेता हूं (डिफ़ॉल्ट रूप से लगभग 32/200% गैर प्रिंटबेल के साथ)। जीसी, इनिशियलाइज़ेशन वगैरह जैसे सामान का ध्यान रखना चाहिए - इतना अधिक ओवरहेड नहीं है कि किसी भी एल्गोरिथ्म में बिना किसी बाधा के कम से कम एक रन होना चाहिए।

विशेष रूप से अच्छी तरह से प्रलेखित नहीं है, लेकिन ओह अच्छी तरह से। यहाँ हम चलते हैं - मैंने शाफ़्ट के दोनों एल्गोरिदम और मूल संस्करण को शामिल किया। फिलहाल मैं बेतरतीब ढंग से सीमा में समान रूप से वितरित चार्ट के साथ एक 200 चार्ट लंबी स्ट्रिंग को प्रारंभिक करता हूं [0, 200)।


प्रयास के लिए +1 - लेकिन आपको मुझसे पूछना चाहिए था - मेरे पास पहले से ही एक समान बेंचमार्किंग सूट है - यही वह जगह है जहां मैं अपने एल्गोरिदम का परीक्षण कर रहा था;)
ग्रेचैट

@ ग्रेकैट वैसे तो मैं कर सकता था, लेकिन बस एक साथ फेंकना (मौजूदा कोड वैसे भी) शायद तेजी से था;)
वू

1

आईएएनए निम्न-स्तरीय जावा प्रदर्शन दीवाने हैं, लेकिन क्या आपने अपने मुख्य लूप को अनियंत्रित करने की कोशिश की है ? ऐसा प्रतीत होता है कि यह कुछ सीपीयू को समानांतर में जांच करने की अनुमति दे सकता है।

इसके अलावा, इस अनुकूलन के लिए कुछ मज़ा विचारों है।


मुझे संदेह है कि यहां कोई भी अनियंत्रण किया जा सकता है, क्योंकि पिछले चरणों में एल्गोरिथम के निम्नलिखित चरणों पर निर्भरताएं हैं (बी), मैंने किसी को जावा में किसी भी तारकीय परिणाम का उत्पादन करने वाले मैनुअल लूप को अनलॉक्ड करने के बारे में नहीं सुना है; जेआईटी आमतौर पर जो भी कार्य को देखता है, उसे अनियंत्रित करने में एक अच्छा काम करता है। सुझाव और एक लिंक के लिए धन्यवाद, हालांकि :)
ग्रेचैट

0

क्यों "utf-8" चारसेट नाम का उपयोग करने से सीधे पूर्व-आवंटित स्थैतिक का उपयोग करने से बेहतर प्रदर्शन होता है Charset.forName ("utf-8")?

यदि आप String#getBytes("utf-8")आदि का मतलब है : यह तेजी से नहीं होना चाहिए - कुछ बेहतर कैशिंग के अलावा - चूंकि Charset.forName("utf-8")आंतरिक रूप से उपयोग किया जाता है, अगर चारसेट को कैश नहीं किया गया है।

एक बात यह हो सकती है कि आप अलग-अलग वर्णमाला का उपयोग कर रहे हैं (या हो सकता है कि आपका कोई कोड पारदर्शी तरीके से करता हो) लेकिन चारसेट में StringCodingपरिवर्तन नहीं हुआ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.