क्या जावास्क्रिप्ट में एक निर्मित स्ट्रिंगर वर्ग है?


जवाबों:


318

यदि आपको इंटरनेट एक्सप्लोरर के लिए कोड लिखना है तो सुनिश्चित करें कि आपने एक कार्यान्वयन चुना है, जो सरणी जोड़ का उपयोग करता है। IE पर ऑपरेटर +या +=ऑपरेटर के साथ संबंधित स्ट्रिंग्स बेहद धीमी हैं। यह विशेष रूप से IE6 के लिए सच है। आधुनिक ब्राउज़रों +=पर आमतौर पर सरणी के रूप में उपवास के रूप में तेजी से होता है।

जब मुझे बहुत सारे स्ट्रिंग कॉन्सेप्टन करने होते हैं तो मैं आमतौर पर एक एरे को भरता हूं और स्ट्रिंग बिल्डर क्लास का उपयोग नहीं करता हूं:

var html = [];
html.push(
  "<html>",
  "<body>",
  "bla bla bla",
  "</body>",
  "</html>"
);
return html.join("");

ध्यान दें कि pushविधियाँ कई तर्कों को स्वीकार करती हैं।


7
और यदि आप आउटपुट इनलाइन उत्पन्न कर रहे हैं, या सभी सदस्य शाब्दिक हैं, तो [foo(), "bar", "baz"].join("");काम भी करते हैं।
बेनामी

1
जबकि एक शायद लगभग 3 साल तक काम करने के लिए ड्रॉपबॉक्स लिंक की उम्मीद नहीं कर सकता है, मैं तुलना के बारे में उत्सुक हूं - और अगर यह अभी भी जारी है।
कॉर्नेलियस

1
@DaveWard, आपका लिंक टूट गया है :(
इवान कोचरिन

मुझे यह बहुत अधिक पठनीय लगता है कि स्ट्रिंग + स्ट्रिंग + स्ट्रिंग
एंड्रयू एर्लिच

12
मुझे नहीं पता था कि pushकई तर्क स्वीकार कर सकते हैं। यादृच्छिक चीजें आप सीखते हैं।
Carcigenicate

55

मैंने सिर्फ http://jsperf.com/javascript-concat-vs-join/2 पर प्रदर्शन रीचेक किया । परीक्षण-मामले १००० बार वर्णमाला को मिलाते हैं या जुड़ते हैं।

वर्तमान ब्राउज़रों (एफएफ, ओपेरा, आईई 11, क्रोम) में, "कॉनकट" "जॉइन" की तुलना में लगभग 4-10 गुना तेज है।

IE8 में, दोनों समान परिणामों के बारे में लौटते हैं।

IE7 में, "जॉइन" दुर्भाग्य से लगभग 100 गुना तेज है।


3
इसके लिए धन्यवाद। यह उत्तर सूची में टकरा जाना चाहिए। यह IE10 पर भी बहुत तेज है (मुझे पता है कि यह एक आधुनिक ब्राउज़र नहीं है, लेकिन मैं इसे देखने वाले किसी भी संभावित एनएमसीआई डेवलपर्स के लिए इसका उल्लेख करता हूं)।
जेम्स विल्सन

@ और मुझे विश्वास है कि आपका परीक्षण क्रोम में एक कोड पथ को मार रहा है जहां यह कभी वास्तविक समवर्ती नहीं कर रहा है क्योंकि स्ट्रिंग कभी भी पढ़ा नहीं जाता है। जब भी मजबूर किया जाता है, तब भी, निष्पादन की गति अभी भी काफी तेज है: jsperf.com/yet-another-string-concat-test/1
जोसेफ लेनोक्स

37

नहीं, इमारत के तारों के लिए कोई अंतर्निहित समर्थन नहीं है। आपको इसके बजाय कॉनटेनटेशन का उपयोग करना होगा।

आप, निश्चित रूप से, अपने स्ट्रिंग के विभिन्न हिस्सों की एक सरणी बना सकते हैं और फिर join()उस सरणी पर कॉल कर सकते हैं, लेकिन यह तब निर्भर करता है कि आपके द्वारा उपयोग किए जा रहे जावास्क्रिप्ट दुभाषिया में सम्मिलित कैसे लागू किया जाए।

मैंने str1+str2विधि बनाम array.push(str1, str2).join()विधि की गति की तुलना करने के लिए एक प्रयोग किया । कोड सरल था:

var iIterations =800000;
var d1 = (new Date()).valueOf();
str1 = "";
for (var i = 0; i<iIterations; i++)
    str1 = str1 + Math.random().toString();
var d2 = (new Date()).valueOf();
log("Time (strings): " + (d2-d1));

var d3 = (new Date()).valueOf();
arr1 = [];
for (var i = 0; i<iIterations; i++)
    arr1.push(Math.random().toString());
var str2 = arr1.join("");
var d4 = (new Date()).valueOf();
log("Time (arrays): " + (d4-d3));

मैंने इसे इंटरनेट एक्सप्लोरर 8 और फ़ायरफ़ॉक्स 3.5.5 में, विंडोज 7 एक्स 64 पर दोनों का परीक्षण किया।

शुरुआत में मैंने छोटी संख्या में पुनरावृत्तियों (कुछ सौ, कुछ हजार आइटम) पर परीक्षण किया। परिणाम अप्रत्याशित थे (कभी-कभी स्ट्रिंग संघनन में 0 मिलीसेकंड लिया जाता था, कभी-कभी इसमें 16 मिली सेकेंड लगते थे, वही सरणी में शामिल होने के लिए)।

जब मैंने गिनती को 50,000 तक बढ़ा दिया, तो परिणाम अलग-अलग ब्राउज़रों में अलग-अलग थे - इंटरनेट एक्सप्लोरर में स्ट्रिंग का संघनन तेज (94 मिलीसेकंड) था और इसमें शामिल होने की गति धीमी (125 मिलीसेकंड) थी, जबकि फ़ायरफ़ॉक्स में सरणी जुड़ाव तेज़ (113 मिलीसेकंड) से अधिक था स्ट्रिंग जॉइनिंग (117 मिलीसेकंड)।

फिर मैंने गिनती बढ़ाकर 500'000 कर दी। अब दोनों ब्राउजरों में स्ट्रिंग कॉन्टेनेटेशन की तुलनाarray.join() में धीमी थी : इंटरनेट एक्सप्लोरर में स्ट्रिंग कॉनटेनेंस 937 एमएस था, फायरफॉक्स में 1155 एमएस, इंटरनेट एक्सप्लोरर में सरणी 1265 और फायरफॉक्स में 1207 एमएस शामिल है।

"स्क्रिप्ट को निष्पादित करने में बहुत लंबा समय लग रहा है" होने के बिना मैं इंटरनेट एक्सप्लोरर में अधिकतम पुनरावृत्ति गणना कर सकता था, 850,000 थी। तब इंटरनेट एक्सप्लोरर स्ट्रिंग कॉन्सेप्टन के लिए 1593 और एरे जॉइन के लिए 2046 था, और फ़ायरफ़ॉक्स में स्ट्रिंग कॉन्क्वेनेशन के लिए 2101 और एरे जॉइन के लिए 2249 था।

परिणाम - यदि पुनरावृत्तियों की संख्या छोटी है, तो आप उपयोग करने का प्रयास कर सकते हैं array.join(), क्योंकि यह फ़ायरफ़ॉक्स में तेज़ हो सकता है। जब संख्या बढ़ती है, तो string1+string2विधि तेज होती है।

अपडेट करें

मैंने इंटरनेट एक्सप्लोरर 6 (विंडोज एक्सपी) पर परीक्षण किया। यदि मैंने 100,000 से अधिक पुनरावृत्तियों पर परीक्षण की कोशिश की, तो प्रक्रिया तुरंत जवाब देने के लिए बंद हो गई और कभी समाप्त नहीं हुई। 40,000 पुनरावृत्तियों पर परिणाम थे

Time (strings): 59175 ms
Time (arrays): 220 ms

इसका मतलब है - यदि आपको इंटरनेट एक्सप्लोरर 6 का समर्थन करने की आवश्यकता है, तो चुनें array.join()कि स्ट्रिंग संधि की तुलना में कौन सा तेज़ है।


join()ECMAScript का हिस्सा है और प्रत्येक जावास्क्रिप्ट दुभाषिया इसे लागू करता है। यह "निर्भर" क्यों होगा?
एली ग्रे

उनका मतलब था कि इसे कैसे लागू किया गया ... अगर इसे इस तरह से लागू किया जाता है कि, एक लूप में, स्ट्रिंग को लगातार एक ही बार में बनाए जाने का विरोध किया जाता है, तो जॉइन का उपयोग व्यर्थ होगा
जॉन

हाँ, यह वही था जो मैं वास्तव में था। मेरी अंग्रेजी क्षमा करें ;-) मैंने दो ब्राउज़रों में किस विधि से कितनी तेजी से काम किया इसकी तुलना के परिणाम जोड़े। आप देख सकते हैं, यह अलग है।
भिवानी

2
IE6, हमेशा की तरह, अपवाद है :)
गॉर्डन टकर

10
IE6 के साथ लोगों को सब कुछ वास्तव में धीमी गति से होने के लिए उपयोग किया जाता है। मुझे नहीं लगता कि वे आपको दोषी ठहराएंगे।
Lodewijk

8

यह कोड उस मार्ग की तरह दिखता है जिसे आप कुछ बदलावों के साथ लेना चाहते हैं।

आप इस तरह दिखने के लिए परिशिष्ट विधि बदलना चाहते हैं। मैंने इसे 0 नंबर स्वीकार करने के लिए बदल दिया है, और इसे वापस करने के लिए thisताकि आप अपने ऐप्पल को चेन कर सकें।

StringBuilder.prototype.append = function (value) {
    if (value || value === 0) {
        this.strings.push(value);
    }
    return this;
}

केवल गैर-NaN संख्या और गैर-रिक्त स्ट्रिंग को क्यों स्वीकार करें? आपका विधि को स्वीकार नहीं करेगा null, false, रिक्त स्ट्रिंग, undefinedया NaN
एली ग्रे

@ एलिजा - मैं कुछ भी मान्य मान्य और संख्याओं को स्वीकार नहीं करके अपने स्ट्रिंगबर्ल क्लास को साफ रखना पसंद करती हूं। यह सिर्फ एक व्यक्तिगत प्राथमिकता है।
गॉर्डन टकर

5

जावास्क्रिप्ट के ECMAScript 6 संस्करण (उर्फ ECMAScript 2015) ने स्ट्रिंग शाब्दिक शुरुआत की ।

var classType = "stringbuilder";
var q = `Does JavaScript have a built-in ${classType} class?`;

ध्यान दें कि सिंगल-कोट्स के बजाय, बैक-टिक्स, स्ट्रिंग को संलग्न करते हैं।


17
यह प्रश्न का उत्तर कैसे देता है?
पीटर मोर्टेंसन

@ पेटर मोर्टेंसन, यह उत्तर केवल एक स्ट्रिंग बनाने का एक और तरीका देता है। मूल पोस्टर में यह निर्दिष्ट नहीं किया गया था कि स्ट्रिंग बिल्डर कार्यक्षमता किस प्रकार की मांगी जा रही है।
थियोफिलस

1
इस सवाल का जवाब नहीं है। बिल्कुल भी।
मासिमिलियानो क्रूस

2

C # में आप कुछ ऐसा कर सकते हैं

 String.Format("hello {0}, your age is {1}.",  "John",  29) 

जावास्क्रिप्ट में आप कुछ ऐसा कर सकते हैं

 var x = "hello {0}, your age is {1}";
 x = x.replace(/\{0\}/g, "John");
 x = x.replace(/\{1\}/g, 29);

2
मुझे अत्यधिक संदेह है कि एक स्ट्रिंग ज्वाइन के स्थान पर एक नियमित अभिव्यक्ति चलने से अधिक प्रदर्शन होगा
टिक

इसके अलावा, यह एक भयानक कार्यान्वयन है। यह टूट जाएगा अगर स्ट्रिंग जिसके साथ {0}प्रतिस्थापित किया गया है {1}
इकेगामी

@ikegami स्ट्रिंग एक चर नहीं है, एक स्थिर है, इसलिए आपको पता है कि व्हाट्सएप में एक प्राथमिकता शामिल थी।
खेल

@sports, कॉपी करना और अपने पूरे कोड में पेस्ट करना एक और भी बुरा विचार है।
इकेगामी

$ 1 और $ 2 के साथ एक लाइनर गैर-कैप्चर समूहों को प्रतिस्थापित कर रहा है: x..replace (/ ([\ s s s] *?) \ {0 \} ([\ s \ S] *?) \ {1 \} / जी, "$ 1Tom $ 225")
T.CK

1

रुचि रखने वालों के लिए, यहाँ Array.join को लागू करने का एक विकल्प है:

var arrayOfStrings = ['foo', 'bar'];
var result = String.concat.apply(null, arrayOfStrings);
console.log(result);

आउटपुट, जैसा कि अपेक्षित था, स्ट्रिंग 'फोब्बर' है। फ़ायरफ़ॉक्स में, यह दृष्टिकोण Array.join से आगे निकल जाता है, लेकिन outatformed + concatenation द्वारा होता है। चूंकि String.concat को प्रत्येक खंड को एक अलग तर्क के रूप में निर्दिष्ट करने की आवश्यकता होती है, इसलिए कॉल करने वाला जावास्क्रिप्ट इंजन द्वारा निष्पादित किसी भी तर्क गणना सीमा द्वारा सीमित होता है। अधिक जानकारी के लिए Function.prototype.apply () के प्रलेखन पर एक नज़र डालें ।


Chrome में यह विफल हो जाता है, क्योंकि "String.concat" अपरिभाषित है। इसके बजाय, आप '' .concat.apply ('', arrayOfStrings) का उपयोग कर सकते हैं। लेकिन यह अभी भी बहुत धीमी विधि है।
एंड्रियास

1

मैंने इस फ़ंक्शन को परिभाषित किया है:

function format() {
        var args = arguments;
        if (args.length <= 1) { 
            return args;
        }
        var result = args[0];
        for (var i = 1; i < args.length; i++) {
            result = result.replace(new RegExp("\\{" + (i - 1) + "\\}", "g"), args[i]);
        }
        return result;
    }

और सी # की तरह बुलाया जा सकता है:

 var text = format("hello {0}, your age is {1}.",  "John",  29);

परिणाम:

हैलो जॉन, आपकी उम्र 29 है।


1
मुझे यह पसंद है ... सी #
आयो अदिसिना

2
इस जवाब का सवाल से कोई लेना-देना नहीं है।
मासिमिलियानो क्रूस

0

जब मैं अपने आप को जावास्क्रिप्ट में बहुत सारे स्ट्रिंग संयोजन का काम करता हुआ पाता हूं, तो मैं टेंपलेटिंग की तलाश शुरू करता हूं। HTML और JavaScript को अधिक पठनीय रखने के लिए Handlebars.js काफी अच्छी तरह से काम करता है। http://handlebarsjs.com


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