ES6 टेम्पलेट शाब्दिक स्ट्रिंग संघनन की तुलना में तेज़ हैं?


82

ES6 में स्ट्रिंग संघनन या टेम्पलेट शाब्दिक का उपयोग करते समय क्या एचटीएमएल कोड पीढ़ी आधुनिक ब्राउज़रों में तेजी से चलती है?

उदाहरण के लिए:

स्ट्रिंग संगति

"<body>"+
  "<article>"+
    "<time datetime='" + date.toISOString() +"'>"+ date +"</time>"+
  "</article>"+
"</body>"

खाका शाब्दिक

`<body>
  <article>
    <time datetime='${ date.toISOString() }'>${ date }</time>
  </article>
</body>`

2
स्ट्रिंग संघनन पर्याप्त धीमा नहीं है कि सुधार के लिए ध्यान देने योग्य कमरा है। मूंछें / अंडरस्कोर / हैंडलबार जैसे लोकप्रिय टेम्प्लेटर्स दर्जनों से सैकड़ों गुना धीमे होते हैं, जैसे कि समतलता या टेम्प्लेट शाब्दिक होगा।
डंडविस

1
सैद्धांतिक बोल (जब तक कि जेएस संकलित नहीं किया जाता है), टेम्पलेट शाब्दिक धीमे होंगे क्योंकि 'स्ट्रिंग' को प्लेसहोल्डर अस्तित्व की परवाह किए बिना पार्स करने की आवश्यकता है। जेएस इंजन एक बार टेम्पलेट शाब्दिक रूप से पार्स करेगा ताकि बाद के उपयोग केवल उपजी स्ट्रिंग के रूप में तेज़ हों; इसका अर्थ है कि केवल एक बार टेम्पलेट शाब्दिक रूप से पार्स करने के लिए आवश्यक अंतर होगा।
प्रीसैस्टिक

पाठ्यक्रम का स्ट्रिंग संघनन तेज है। कोई पार्सिंग नहीं चल रही है। यह सिर्फ स्ट्रिंग की लंबाई को जोड़ रहा है। फिर भी मैं खाका शाब्दिक उपयोग करूँगा।
बैंजोकेट

मैंने इस प्रश्न को बंद करने के लिए मतदान किया है क्योंकि परिणाम गैर-निर्णायक हैं। 1. गति इंजन पर निर्भर करेगा - बहुत कम से कम हो सकता है (और वहाँ है लेखन के समय) Chrome और Firefox के बीच का अंतर। 2. गति इस बात पर निर्भर करेगी कि कैसे संघनन / टेम्पलेट्स का उपयोग किया जाता है और किस डेटा के साथ। 3. ये एक ही इंजन के विभिन्न संस्करणों के बीच बदल सकते हैं। 4. माइक्रोबेनमार्किंग भ्रामक परिणाम उत्पन्न कर सकती है। 5. गति में अंतर, यदि कोई हो, नगण्य होने की संभावना है। लेखन के समय यह है
VLAZ

जवाबों:


86

यह क्षण के लिए लगता है स्ट्रिंग का संघनन तेज है: http://jsperf.com/es6-string-literals-vs-string-concatenation

ES6 with variable                     19,992,512    ±5.21%    78% slower
String concatenation with variable    89,791,408    ±2.15%    fastest
ES6 with function                     461,358       ±3.12%    99% slower
String concatenation with function    503,255       ±1.77%    99% slower

मैंने परीक्षण किया था क्रोम 43.0.2334.0 कैनरी (64-बिट) पर चलाया गया था, जो कि #enable-javascript-harmonyध्वज को सक्षम करने के साथ V8 4.3.31 का उपयोग कर रहा है ।

संदर्भ के लिए, Node.js (लेखन के समय 0.12.0) पर नवीनतम संस्करण V8 3.28.73 का उपयोग कर रहा है: https://raw.githubusercontent.com/joyent/node/master/ChangeLog

मुझे यकीन है कि सभी संभावित प्रदर्शन अनुकूलन जो लागू किए जा सकते हैं, अभी तक लागू नहीं किए गए हैं, इसलिए प्रदर्शन की उम्मीद करना उचित होगा क्योंकि ES6 अंतिम रूप से नजदीक हो जाता है और ये सुविधाएँ स्थिर शाखा में स्थानांतरित हो जाती हैं।


संपादित करें: टिप्पणियों के लिए धन्यवाद @ user1329482, @ icl7126, निकोलाई बोरिसिक और फस्टरक्लाक। अब जब यह प्रश्न पूछे जाने के बाद लगभग 2 वर्ष बीत चुके हैं, ES6 ब्राउज़र समर्थन बहुत बढ़ गया है, और प्रदर्शन अनुकूलन की एक अच्छी मात्रा हुई है। यहाँ कुछ अद्यतन हैं

संपादित करें: (फरवरी 2020) @ JorgeFuentesGonzález टिप्पणियों और बाद की पुष्टि के आधार पर क्रोम परिणाम अपडेट किया गया

Chrome में (59.0.3035 के रूप में), ES6 स्ट्रिंग शाब्दिक तेज़ हैं :

ES6 with variable                     48,161,401       ±1.07%    fastest
String concatenation with variable    27,046,298       ±0.48%    44% slower
ES6 with function                     820,441          ±1.10%    98% slower
String concatenation with function    807,088          ±1.08%    98% slower

अपडेट: क्रोम में (79.0.3945 के रूप में), स्ट्रिंग तेज है ... टिप्पणियां देखें।

फ़ायरफ़ॉक्स में (57.0.0 के अनुसार), ES6 स्ट्रिंग शाब्दिक तेज़ हैं :

ES6 with variable                     1,924,610,984    ±0.50%    fastest
String concatenation with variable    1,876,993,458    ±0.79%    3% slower
ES6 with function                     539,762          ±5.04%    100% slower
String concatenation with function    546,030          ±5.88%    100% slower

सफारी में (11.0.2 के अनुसार), यह निर्भर करता है:

ES6 with variable                     1,382,752,744    ±0.71%    fastest
String concatenation with variable    1,355,512,037    ±0.70%    2% slower
ES6 with function                     876,516          ±1.01%    100% slower
String concatenation with function    883,370          ±0.79%    100% slower

टाइपकास्ट स्ट्रिंग का उपयोग करते समय, ES6 स्ट्रिंग लीटर तेजी से होते हैं । हालांकि, शाब्दिक से एक फ़ंक्शन को कॉल करते समय, इस उदाहरण में स्ट्रिंग का संघनन तेज होता है।

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


4
फ़ायरफ़ॉक्स 50 64 बिट - ES6 में गति समान है 1,423,816,207 ऑप्स / एस।
icl7126

4
सफारी 9.0 ES6 प्रक्षेप 34 गुना क्रोम के बारे में तेजी से 55 क्रोम अभी भी ES6 प्रक्षेप बहुत धीमी फ़ायरफ़ॉक्स 50 एक ही गति
निकोलाई बोरिसिक

1
टेम्प्लेट स्ट्रिंग्स अब स्ट्रिंग समवर्ती की तुलना में तेजी का परिमाण है। दिए गए jsperf का संस्करण 14 देखें, यह सबसे सटीक और निष्पक्ष है जो तकनीकी रूप से फीचर पहलुओं को बनाए रखते हुए प्राप्त कर सकता है। संस्करण 17 कम से कम पक्षपातपूर्ण लेकिन अवास्तविक है।
FesterCluck

1
Jsperf लिंक जो आपने पास किया, "संशोधन 1" में, स्ट्रिंग क्रोमलल्स
जॉर्ज

1
Jsperf रिजल्ट फाइल डिलीट हो गई। इसे समाप्ति के बिना अपलोड किया गया: u.teknik.io/02OVr.png
जॉर्ज

7

मैंने नोड.जेएस v6.0.0 पर एक अनुभवहीन परीक्षण किया और लगभग उसी प्रदर्शन को प्राप्त किया । चूंकि परीक्षण इतना अनुभवहीन है, संख्याओं पर बहुत अधिक विश्वास न करें। लेकिन ऐसा लगता है कि जेआईटी कंपाइलर आजकल बहुत अनुकूलित कोड बनाता है। यह मुझे अपने नोड एप्स के लिए कॉन्टैकटेशन पर टेम्प्लेट को प्राथमिकता देने का निर्णय लेने देता है।

संदर्भ के लिए यह मेरे द्वारा उपयोग किया जाने वाला कोड है:

'use strict'

function strConcat(i) {
    return 'abc' + i + 'def'
}

function strTemplate(i) {
    return `abc${i}def`
}

function run(strategy) {
    let before = new Date().getTime()
    let len = 0
    for ( let i = 0; i < 10000000; i+=1 ) {
        len += strategy(i).length
    }
    console.log(len + ' - ' + ((new Date().getTime()) - before) + 'ms')
}

console.log('strConcat')
run(strConcat)

console.log('strTemplate')
run(strTemplate)

और आउटपुट था:

strConcat
128888890 - 1904ms
strTemplate
128888890 - 1979ms

मैं lenपूरी तरह से यह सुनिश्चित करने के लिए इस्तेमाल किया गया था कि ऑप्टिमाइज़र दूर से पूरे लूप का अनुकूलन न करे। वैसे भी, यह अभी भी एक बहुत ही सरल परीक्षा है। शायद कोई और अधिक परिष्कृत बना सकता है।


1
मैंने एक समान बेंचमार्क चलाया और एक समान परिणाम प्राप्त किया। मेरे बेंचमार्क में अधिक तार शामिल थे, जिनमें से कुछ लंबे थे। अंतर्वेशन संघनन की तुलना में थोड़ा बेहतर प्रदर्शन करता है।
रैट्रे

2

स्ट्रिंग के रूप में यादृच्छिक संख्याओं के साथ एक सरल परीक्षण के लिए, दोनों क्रोम और एफएफ में इतने करीब आ रहे हैं

Chrome में परीक्षण 58.0.3029 / विंडोज 10

स्ट्रिंग शाब्दिक 2,996,883% 2.36% सबसे तेज

ऑपरेटर (+) 3,054,078% 2.01% सबसे तेज

कॉनकैट फ़ंक्शन 2,659,391 function 2.35% 13% धीमा

फ़ायरफ़ॉक्स में परीक्षण 53.0.2 / विंडोज 10

स्ट्रिंग शाब्दिक 1,923,835 9 1.52% सबसे तेज

ऑपरेटर (+) 1,948,503 1, 1.13% सबसे तेज

कॉनकैट फ़ंक्शन 1,810,857 10 1.81% 8% धीमा

यहाँ jsperf पर टेस्ट करें


1

टी एल; डॉ

इसकी गति के बारे में सामंजस्य तेज और अधिक सुसंगत है। लेकिन अंतर 1 या 2 चर (100 मिलियन कॉल के लिए .3 सेकंड से कम) के लिए बहुत कम है।

संपादित करें

दूसरे रन के बाद ऐसा लगता है कि कॉन्सेप्टेशन ज्यादातर दोनों का तेज है।


इसलिए, मैं एक परीक्षण प्रदान करके एनालॉग-निको के उत्तर का विस्तार करना चाहता था जो कि अधिक व्यापक था और दोनों कार्यों की मापनीयता में भी (थोड़ा) देखा गया था।

पास्टबिन पर कोड

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

बाद में, मैंने प्रत्येक विधि के लिए औसत, न्यूनतम, अधिकतम और मानक विचलन की गणना की।

यहाँ परिणाम हैं:

{ 
  sum: { 
    t: { 
      start: 2072751, 
      mid: 2338476, 
      end: 2083695, 
      double: 2950287 
    },
    c: { 
      start: 2086059, 
      mid: 2345551, 
      end: 2074732, 
      double: 2922929 
    } 
  },
  avg: { 
    t: { 
      start: 20727.51,
      mid: 23384.76,
      end: 20836.95,
      double: 29502.87 
    },
    c: { 
      start: 20860.59,
      mid: 23455.51,
      end: 20747.32,
      double: 29229.29 
    } 
  },
  sd: {
    t: {
      start: 335.6251329981114,
      mid: 282.9490809315344,
      end: 286.2220947096852,
      double: 216.40844045461824 
    },
    c: {
      start: 255.4803356424913,
      mid: 221.48744862858484,
      end: 238.98242111084238,
      double: 209.9309074433776 
    } 
  },
  min: { 
    t: { 
      start: 20490, 
      mid: 23216, 
      end: 20588, 
      double: 29271 
    },
    c: { 
      start: 20660, 
      mid: 23258, 
      end: 20534, 
      double: 28985 
    } 
  },
  max: { 
    t: { 
      start: 23279, 
      mid: 25616, 
      end: 22887, 
      double: 30843 
    },
    c: { 
      start: 22603, 
      mid: 25062, 
      end: 22403, 
      double: 30536 
    } 
  } 
}

t-objects में मान टेम्प्लेट के लिए हैं, c-objects में मान कॉनटेनेंस के लिए हैं। startइसका मतलब है कि चर शुरुआत में है, मध्य है कि यह मध्य में है, अंत यह है कि यह अंत में है और दोगुना है कि दो चर हैं। sumसभी 100 रन का योग है। avgऔसत रन है, जिसका अर्थ है sum / 100sd यहाँ आसान तरीका है, विकिपीडिया (सरल अंग्रेजी)minऔर maxएक रन का न्यूनतम और अधिकतम मूल्य क्रमशः है।

परिणाम

ऐसा लगता है कि एकल चर के लिए टेम्प्लेट तेज़ होते हैं जो स्ट्रिंग के अंत में स्थित नहीं होते हैं, यह देखते हुए कि औसत कम है और न्यूनतम कम है। यदि आप एक स्ट्रिंग के अंत में एक चर डालते हैं या आपके स्ट्रिंग में कई चर होते हैं, तो संघनन तेज होता है।

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

चूँकि अधिकांश टेम्प्लेट्स का उपयोग शायद एक स्ट्रिंग में केवल एक चर के लिए नहीं किया जाएगा, इसलिए यह कहना बच जाता है कि कंफर्टेशन के लिए चिपके रहने से बेहतर प्रदर्शन मिलता है। लेकिन अंतर बहुत कम है (अभी के लिए कम से कम)। दो चर के साथ 100,000,000 (100 मिलियन) मूल्यांकन में, अंतर केवल 273,58 एमएस है, एक चौथाई सेकंड के बारे में ...


दूसरा रन

दूसरा रन कुछ अलग दिखता है। अधिकतम मान को छोड़कर, औसत निरपेक्ष विचलन और मानक विचलन, प्रत्येक माप ने इस बात का प्रमाण दिया कि संघनन टेम्पलेट्स की तुलना में अधिक तेज़ है।

तीन उल्लिखित मापों में टेम्पलेट्स के लिए कम (इस प्रकार बेहतर) मूल्य थे जब चर स्ट्रिंग के अंत में था या जब स्ट्रिंग में दो चर थे।

यहाँ परिणाम हैं:

{
  "sum": {
    "t": {
      "start": 1785103,
      "mid": 1826679,
      "end": 1719594,
      "double": 2110823,
      "many": 4153368
    },
    "c": {
      "start": 1720260,
      "mid": 1799579,
      "end": 1716883,
      "double": 2097473,
      "many": 3836265
    }
  },
  "avg": {
    "t": {
      "start": 17851.03,
      "mid": 18266.79,
      "end": 17195.94,
      "double": 21108.23,
      "many": 41533.68
    },
    "c": {
      "start": 17202.6,
      "mid": 17995.79,
      "end": 17168.83,
      "double": 20974.73,
      "many": 38362.65
    }
  },
  "sd": {
    "t": {
      "start": 858.7857061572462,
      "mid": 886.0941856823124,
      "end": 786.5366719994689,
      "double": 905.5376950188214,
      "many": 1744.9005638144542
    },
    "c": {
      "start": 599.0468429096342,
      "mid": 719.1084521127534,
      "end": 935.9367719563112,
      "double": 991.5642274204934,
      "many": 1465.1116774840066
    }
  },
  "aad": {
    "t": {
      "start": 579.1207999999996,
      "mid": 576.5628000000003,
      "end": 526.8268,
      "double": 586.9651999999998,
      "many": 1135.9432000000002
    },
    "c": {
      "start": 467.96399999999966,
      "mid": 443.09220000000016,
      "end": 551.1318000000008,
      "double": 610.2321999999999,
      "many": 1020.1310000000003
    }
  },
  "min": {
    "t": {
      "start": 16932,
      "mid": 17238,
      "end": 16387,
      "double": 20016,
      "many": 39327
    },
    "c": {
      "start": 16477,
      "mid": 17137,
      "end": 16226,
      "double": 19863,
      "many": 36424
    }
  },
  "max": {
    "t": {
      "start": 23310,
      "mid": 24102,
      "end": 21258,
      "double": 26883,
      "many": 49103
    },
    "c": {
      "start": 19328,
      "mid": 23203,
      "end": 22859,
      "double": 26875,
      "many": 44352
    }
  },
  "median": {
    "t": {
      "start": 17571,
      "mid": 18062,
      "end": 16974,
      "double": 20874,
      "many": 41171.5
    },
    "c": {
      "start": 16893.5,
      "mid": 18213,
      "end": 17016.5,
      "double": 20771,
      "many": 38849
    }
  }
}

कोड यहाँ है


मैं वर्तमान में अपनी परीक्षण स्क्रिप्ट का एक नया संस्करण चला रहा हूं। इसमें absolute average meanऔर शामिल हैं median। यह 10 चर के साथ रनटाइम को भी बदलता है।
आर्मिन

0

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

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