v8 জাভাস্ক্রিপ্ট পারফরম্যান্স এর কনস্ট, প্রভাব, এবং এর প্রভাব?


90

কার্যকরী পার্থক্য নির্বিশেষে, নতুন কীওয়ার্ডগুলি 'লেট' এবং 'কনট' ব্যবহার করে 'ভার' এর সাথে সম্পর্কিত কোনও পারফরম্যান্সের উপর কোনও সাধারণীকরণ বা নির্দিষ্ট প্রভাব পড়ে?

প্রোগ্রামটি চালানোর পরে:

function timeit(f, N, S) {
    var start, timeTaken;
    var stats = {min: 1e50, max: 0, N: 0, sum: 0, sqsum: 0};
    var i;
    for (i = 0; i < S; ++i) {
        start = Date.now();
        f(N);
        timeTaken = Date.now() - start;

        stats.min = Math.min(timeTaken, stats.min);
        stats.max = Math.max(timeTaken, stats.max);
        stats.sum += timeTaken;
        stats.sqsum += timeTaken * timeTaken;
        stats.N++
    }

    var mean = stats.sum / stats.N;
    var sqmean = stats.sqsum / stats.N;

    return {min: stats.min, max: stats.max, mean: mean, spread: Math.sqrt(sqmean - mean * mean)};
}

var variable1 = 10;
var variable2 = 10;
var variable3 = 10;
var variable4 = 10;
var variable5 = 10;
var variable6 = 10;
var variable7 = 10;
var variable8 = 10;
var variable9 = 10;
var variable10 = 10;

function varAccess(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += variable1;
        sum += variable2;
        sum += variable3;
        sum += variable4;
        sum += variable5;
        sum += variable6;
        sum += variable7;
        sum += variable8;
        sum += variable9;
        sum += variable10;
    }
    return sum;
}

const constant1 = 10;
const constant2 = 10;
const constant3 = 10;
const constant4 = 10;
const constant5 = 10;
const constant6 = 10;
const constant7 = 10;
const constant8 = 10;
const constant9 = 10;
const constant10 = 10;

function constAccess(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += constant1;
        sum += constant2;
        sum += constant3;
        sum += constant4;
        sum += constant5;
        sum += constant6;
        sum += constant7;
        sum += constant8;
        sum += constant9;
        sum += constant10;
    }
    return sum;
}


function control(N) {
    var i, sum;
    for (i = 0; i < N; ++i) {
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
        sum += 10;
    }
    return sum;
}

console.log("ctl = " + JSON.stringify(timeit(control, 10000000, 50)));
console.log("con = " + JSON.stringify(timeit(constAccess, 10000000, 50)));
console.log("var = " + JSON.stringify(timeit(varAccess, 10000000, 50)));

.. আমার ফলাফলগুলি নিম্নলিখিত ছিল:

ctl = {"min":101,"max":117,"mean":108.34,"spread":4.145407097016924}
con = {"min":107,"max":572,"mean":435.7,"spread":169.4998820058587}
var = {"min":103,"max":608,"mean":439.82,"spread":176.44417700791374}

তবে এখানে উল্লিখিত আলোচনাটি মনে হয়েছে যে কিছু পরিস্থিতিতে বিভিন্ন পারফরম্যান্সের পার্থক্যের সম্ভাবনা রয়েছে: https://esdiscuss.org/topic/performance-concern-with-let-const


আমি মনে করি এটি ব্যবহারের উপর নির্ভর করে, উদাহরণস্বরূপ letব্লক স্কোপে ব্যবহৃত ব্যবহারকারীর চেয়ে বেশি পারফরম্যান্স হওয়া উচিত var, যার ব্লক স্কোপ নেই তবে কেবল ফাংশনের সুযোগ রয়েছে।
অ্যাডিনিও

যদি আমি জিজ্ঞাসা করতে পারি যে @ অ্যাডিনিও কেন?
sean2078

4
@ সান ২০৮৮ - আপনার যদি এমন কোনও পরিবর্তনশীল ঘোষণা করতে হয় যা কেবলমাত্র একটি ব্লক স্কোপে থাকে, letতা করে, এবং তারপরে আবর্জনা সংগ্রহ করা হবে var, যা ফাংশনটি বিস্তৃত রয়েছে, প্রয়োজনে একইভাবে কাজ করবে না। আবার ভাবি, এটা এত ব্যবহার নির্দিষ্ট উভয় যে এর letএবং const করতে আরো performant, কিন্তু সবসময় হতে হবে।
অ্যাডিনিও

4
আমি উদ্ধৃত কোড মধ্যে কোনো পার্থক্য প্রকট বোঝানো হয় দ্বারা বিভ্রান্ত করছি varএবং let: এটা কখনোই ব্যবহার letএ সব।
টিজে ক্রাউডার

4
বর্তমানে তা নয় - কেবল কনস্টেম বনাম ভার্ .. .. মূলত gist.github.com/srikumark/1431640 থেকে প্রাপ্ত ( শ্রীকুমার্সের কৃতিত্ব) তবে
কোডটিকে

উত্তর:


123

টিএল; ডিআর

তাত্ত্বিকভাবে , এই লুপটির একটি অপ্রচলিত সংস্করণ:

for (let i = 0; i < 500; ++i) {
    doSomethingWith(i);
}

এর সাথে একই লুপের একটি অপ্রচলিত সংস্করণের চেয়ে ধীর হতে পারে var:

for (var i = 0; i < 500; ++i) {
    doSomethingWith(i);
}

কারণ প্রতিটি লুপের পুনরাবৃত্তির জন্য একটি পৃথক i ভেরিয়েবল তৈরি করা হয় let, তবে সেখানে কেবল একটিই iরয়েছে var

এর বিরুদ্ধে তর্ক করা সত্যটি varউত্তোলন করা হয় তাই এটি লুপের বাইরে letঘোষণা করা হয় তবে লুপের মধ্যে কেবলমাত্র ঘোষিত হয়, এটি একটি অপ্টিমাইজেশন সুবিধা দিতে পারে।

অনুশীলনে , এখানে 2018 সালে, আধুনিক জাভাস্ক্রিপ্ট ইঞ্জিনগুলি কখন এই পার্থক্যটিকে অপ্টিমাইজ করতে পারে তা জানতে লুপের পর্যাপ্ত পরিমাণে অন্তর্নির্ধারণ করে। (তারও আগে, আপনার letলুপগুলি যথেষ্ট কাজ করছিল যে অতিরিক্ত সম্পর্কিত সম্পর্কযুক্ত ওভারহেড যেভাবেই ধুয়ে ফেলা হয়েছে But তবে এখন আপনাকে এটি নিয়েও চিন্তা করতে হবে না))

সিনথেটিক বেঞ্চমার্কগুলি সাবধান থাকুন যেহেতু তারা ভুল পেতে চূড়ান্ত সহজ, এবং জাভাস্ক্রিপ্ট ইঞ্জিন অপ্টিমাইজারগুলিকে এমন পদ্ধতিতে ট্রিগার করুন যাতে আসল কোড হয় না (ভাল এবং খারাপ উভয় উপায়ে)। তবে, আপনি যদি একটি সিনথেটিক মানদণ্ড চান, এখানে একটি:

এটি বলে যে ভি 8 / ক্রোম বা স্পাইডারমনকি / ফায়ারফক্সের যে কোনও একটিতে এই সিন্থেটিক পরীক্ষার কোনও উল্লেখযোগ্য পার্থক্য নেই। (উভয় ব্রাউজারে পুনরাবৃত্তি পরীক্ষার একটি জিতেছে, বা অন্যটি বিজয়ী হয়েছে এবং উভয় ক্ষেত্রেই ত্রুটির ব্যবধানের মধ্যে রয়েছে) তবে) আবার এটি একটি সিনথেটিক বেঞ্চমার্ক, আপনার কোড নয়। আপনার কোডটির কার্য সম্পাদনের সমস্যা কখন এবং যদি আপনার কোডটির কার্যকারিতা নিয়ে চিন্তিত হন।

শৈলীর বিষয় হিসাবে, আমি letযদি বন্ধের মধ্যে লুপ ভেরিয়েবল ব্যবহার করি তবে আমি স্কোপিং সুবিধা এবং ক্লোজ-ইন-লুপস সুবিধার জন্য পছন্দ করি।

বিশদ

একটি লুপ varএবং এর letমধ্যে গুরুত্বপূর্ণ পার্থক্য forহ'ল iপ্রতিটি পুনরাবৃত্তির জন্য আলাদা তৈরি করা হয়; এটি ক্লাসিক "লুপ ইন ক্লোজার" সমস্যা সম্বোধন করে:

প্রতিটি লুপ বডি (নতুন লিঙ্ক ) এর জন্য নতুন এনভায়রনরেকর্ড তৈরি করা কাজ, এবং কাজ করতে সময় লাগে, যার কারণেই তত্ত্বীয় letসংস্করণটি সংস্করণটির চেয়ে ধীর var

তবে পার্থক্য কেবল তখনই বিবেচিত হয় যদি আপনি লুপের মধ্যে কোনও ফাংশন (ক্লোজার) তৈরি করেন যা ব্যবহার করে i, যেমন আমি উপরের চলমান স্নিপেট উদাহরণে করেছি। অন্যথায়, পার্থক্যটি পর্যবেক্ষণ করা যায় না এবং এটি অপ্টিমাইজ করা যায়।

এখানে 2018 এর মতো দেখে মনে হচ্ছে ভি 8 (এবং ফায়ারফক্সে স্পাইডারমনকি) পর্যাপ্ত অন্তর্নির্ধারণ করছে যে কোনও লুপের কোনও পারফরম্যান্স ব্যয় নেই যা let'এর ভেরিয়েবল-প্রতি-পুনরুক্তকরণ শব্দার্থ ব্যবহার করে না । এই পরীক্ষা দেখুন ।


কিছু ক্ষেত্রে, বিশেষত গ্লোবাল ভেরিয়েবলের constজন্য অপ্টিমাইজেশনের একটি সুযোগ প্রদান করতে পারে যা varনা হয় n't

গ্লোবাল ভেরিয়েবলের সমস্যা হ'ল এটি ভাল, বৈশ্বিক; যে কোনও কোড যে কোনও জায়গায় এটি অ্যাক্সেস করতে পারে। সুতরাং আপনি যদি varএমন কোনও ভেরিয়েবল ঘোষণা করেন যে আপনি কখনই পরিবর্তন করতে চান না (এবং কখনও আপনার কোড পরিবর্তন করেন না), ইঞ্জিন ধরে নিতে পারে না যে এটি পরে বা অনুরূপ লোড কোডের ফলাফল হিসাবে কখনই পরিবর্তন হবে না।

সঙ্গে const, যদিও, আপনি স্পষ্টভাবে ইঞ্জিন যে মান change¹ করতে পারবে না বলছ। সুতরাং কোডগুলি ব্যবহার করে ভেরিয়েবল রেফারেন্সের পরিবর্তে আক্ষরিক নির্গমন সহ এটি যে কোনও অপ্টিমাইজেশন চায় এটি নির্দ্বিধায়, মূল্যবোধগুলি পরিবর্তন করা যায় না তা জেনে।

¹ মনে রাখবেন যে অবজেক্টের সাথে মানটি বস্তুর একটি রেফারেন্স , কোনও বস্তু নিজেই নয়। সুতরাং এর সাহায্যে const o = {}আপনি অবজেক্টের অবস্থা পরিবর্তন o.answer = 42করতে পারেন ( ), তবে আপনি oকোনও নতুন অবজেক্টের দিকে নির্দেশ করতে পারবেন না (কারণ এটিতে থাকা অবজেক্টের রেফারেন্সটি পরিবর্তনের প্রয়োজন হবে)।


ব্যবহার করার সময় letবা constঅন্য- varমতো পরিস্থিতিতে, তাদের আলাদা পারফরম্যান্স হওয়ার সম্ভাবনা থাকে না। আপনি যেমন ব্যবহার করেন varবা letযেমন উদাহরণস্বরূপ: এই ফাংশনটির ঠিক একই কর্মক্ষমতা থাকতে হবে :

function foo() {
    var i = 0;
    while (Math.random() < 0.5) {
        ++i;
    }
    return i;
}

এগুলি অবশ্যই, বিষয়গুলির পক্ষে অসম্ভাব্য এবং কেবল তখনই যখন সমাধান করার জন্য কোনও আসল সমস্যা দেখা দেয় worry


উত্তরের জন্য ধন্যবাদ - আমি সম্মত, সুতরাং লুপ উদাহরণের জন্য আপনার 1 ম তে উল্লিখিত লুপিং অপারেশনের জন্য ভের ব্যবহারের ক্ষেত্রে আমি নিজেরাই প্রমিত হয়েছি, এবং পারফরম্যান্স টেস্ট বলে মনে হয় পারফর্মেন্সের পার্থক্যটি মূলত অস্তিত্বহীন বলে ধরে নিচ্ছি আপাতত নির্দেশ করতে। সম্ভবত পরে, কনস্টের উপর অপ্টিমাইজেশন যুক্ত করা হবে। এটি হ'ল যদি না অন্য কেউ কোড উদাহরণের মাধ্যমে বিবেচনাযোগ্য পার্থক্য না দেখায়।
sean2078

@ সীন ২০৮78: আমি letলুপের উদাহরণেও ব্যবহার করি । পারফরম্যান্সের পার্থক্যটি 99.999% ক্ষেত্রে এটি নিয়ে চিন্তা করার মতো নয়।
টিজে ক্রাউডার

4
মধ্য-2018 সালের হিসাবে, লেটে এবং ভার্সের সংস্করণগুলিতে ক্রোমের একই গতি রয়েছে, সুতরাং এখন আর কোনও পার্থক্য নেই।
সর্বোচ্চ

4
@ ড্যানম: সুসংবাদ, অপ্টিমাইজেশানটি কমপক্ষে ভি 8 এবং স্পাইডারমোনকিতে ধরা পড়েছে। :-)
টিজে ক্রাউডার

4
ধন্যবাদ যথেষ্ট ফর্সা।
হাইপার

20

"এলইটি" লুপ ঘোষণায় আরও ভাল

এর মতো নেভিগেটরে একটি সাধারণ পরীক্ষা (5 বার) সহ:

// WITH VAR
console.time("var-time")
for(var i = 0; i < 500000; i++){}
console.timeEnd("var-time")

নির্বাহের গড় সময়টি 2.5 মিলিয়মের বেশি

// WITH LET
console.time("let-time")
for(let i = 0; i < 500000; i++){}
console.timeEnd("let-time")

কার্যকর করার গড় সময়টি 1.5 মিমি বেশি

আমি দেখতে পেলাম যে লুপের সময়টি আরও ভাল।


7
ফায়ারফক্স 65,0 এই রানিং, আমি গড় গতি পেয়েছে var=138.8msএবং let=4ms। এটি কোনও টাইপো নয়, letবর্তমানে 30x গুণ বেশি দ্রুত
কাটামারি

7
আমি কেবল নোড ভি 12.5 এ এটি ট্রিল করেছি। আমি খুঁজে পেয়েছি গড় গতি var=2.6msএবং let=1.0ms। সুতরাং নোড যাক দ্রুত হিসাবে দ্বিগুণ হিসাবে দ্রুত।
কেনে হুপার

4
অপ্টিমাইজারগুলির উপস্থিতিতে পারফরম্যান্স টেস্টিং কঠোর হবার জন্য কেবলমাত্র স্বাভাবিক বিন্দুটি তৈরি করতে: আমি মনে করি যে লুপটি সম্পূর্ণরূপে অপ্টিমাইজ করা হচ্ছে - কেবলমাত্র ব্লকের ভিতরেই উপস্থিত থাকুক এবং লুপটির কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং ভি 8 এটি জানতে পারে যথেষ্ট স্মার্ট কেবল ব্লকটি সরিয়ে ফেলুন, তারপরে লুপটি। var ঘোষণাটি উত্তোলন করা হয়েছে যাতে এটি এটি জানতে পারে না। আপনার লুপগুলি হ'ল আমি 1 এমএস / 0.4 মিমি পাই, তবে উভয়ের জন্য যদি লুপের বাইরে আমার একটি ভেরিয়েবল জে (ভার বা লেট) থাকে যা বর্ধিত হয় তবে আমি পরে 1 এমএস / 1.5 মিমি পেতে পারি। উদাহরণস্বরূপ, ভের লুপ কোনও পরিবর্তন হয় না, লুপটি এখন আরও বেশি সময় নেয়।
ইউয়ান স্মিথ

@ কেনহুপার - ফায়ারফক্সে যদি আপনি পাঁচগুণ পার্থক্য পেয়ে থাকেন তবে এটি খালি লুপ বডি হতে হবে it আসল লুপগুলিতে খালি দেহ নেই।
টিজে ক্রাউডার

4
সিনথেটিক বেঞ্চমার্কগুলি এবং বিশেষত খালি দেহগুলি সহ লুপগুলি সহ সাবধান হন । আপনি যদি লুপটিতে আসলে কিছু করেন তবে এই সিন্থেটিক বেঞ্চমার্ক (যা আবার, সাবধান! :-)) পরামর্শ দেয় যে এর মধ্যে কোনও উল্লেখযোগ্য পার্থক্য নেই। আমি আমার উত্তরে একটি যুক্ত করে রেখেছি যাতে এটি অন সাইটে রয়েছে (those jscreen পরীক্ষাগুলির মতো নয় যা আমার উপর অদৃশ্য হয়ে গেছে: :-))। বারবার করা রানগুলি একটি জিততে দেখায় বা অন্যটি জিততে পারে। অবশ্যই চূড়ান্ত কিছুই।
টিজে ক্রাউডার

10

টিজে ক্রাউডারের উত্তরটি এত দুর্দান্ত।

এখানে একটি সংযোজন এখানে রয়েছে: "বিদ্যমান বর্ণের বিবরণীগুলি সংশোধন করার ক্ষেত্রে আমি যখন আমার অর্থের জন্য সবচেয়ে বেশি ব্যঙ্গ পাব?"

আমি খুঁজে পেয়েছি যে সর্বাধিক পারফরম্যান্স বুস্টকে "রফতানি" ফাংশনগুলির সাথে করণীয় ছিল।

সুতরাং যদি ফাইল A, B, R, এবং Z ফাইলটি আপনার ইউ এর মাধ্যমে সাধারণত ব্যবহৃত হয় এমন U U ফাইলটিতে একটি "ইউটিলিটি" ফাংশন আহ্বান করে, তবে সেই ইউটিলিটি ফাংশনটিকে "কনস্ট" এ স্যুইচ করা হয় এবং কনস্টের কাছে পিতামাতারা ফাইলের রেফারেন্সটি শুনতে পারে কিছু উন্নত কর্মক্ষমতা আউট। আমার কাছে মনে হয়েছিল এটি পরিমাপযোগ্যভাবে দ্রুত নয়, তবে সামগ্রিক মেমোরি খরচ আমার গুরুতর একাকী ফ্র্যাঙ্কেনস্টাইন-এড অ্যাপ্লিকেশনটির জন্য প্রায় 1-3% হ্রাস পেয়েছিল। যা আপনি যদি ক্লাউড বা আপনার বেয়ারমেটাল সার্ভারে নগদ ব্যাগ ব্যয় করছেন, 30 মিনিট সময় কাটাতে এবং কনস-এর কয়েকটি ঘোষণাপত্র আপডেট করার পক্ষে একটি ভাল কারণ হতে পারে।

আমি বুঝতে পারি যে আপনি কীভাবে কনস্ট, ভার, এবং কভারগুলির নীচে কাজ করতে পারেন তা সম্ভবত আপনি উপরের সিদ্ধান্তটি শেষ করেছেন ... তবে আপনি যদি এটির দিকে "নজর" রেখেছেন: ডি।

আমি আপডেটটি করার সময় নোড v8.12.0 এ বেঞ্চমার্কিংয়ের যা মনে পড়ে তা থেকে আমার অ্যাপ্লিকেশনটি 240MB র‌্যামের নিষ্ক্রিয় ব্যবহার থেকে ~ 233MB র‌্যামে চলে গেছে।


3

টিজে ক্রাউডারের উত্তর খুব ভাল তবে:

  1. 'লেট' কোডটিকে আরও পঠনযোগ্য করে তৈরি করা হয়, আরও শক্তিশালী নয়
  2. তত্ত্ব অনুসারে চলুন var এর চেয়ে ধীর হবে
  3. অনুশীলন দ্বারা সংকলক সম্পূর্ণরূপে সমাধান করতে পারে না (স্থিতিশীল বিশ্লেষণ) একটি অসম্পূর্ণ প্রোগ্রাম যাতে কখনও কখনও এটি অপটিমাইজেশন মিস করবে
  4. যে কোনও ক্ষেত্রে 'লেট' ব্যবহার করে অন্তর্নির্ধারণের জন্য আরও সিপিইউ প্রয়োজন হবে, গুগল ভি 8 পার্স করতে শুরু করলে বেঞ্চটি শুরু করতে হবে
  5. যদি আত্মপরিচয় ব্যর্থ হয় 'লেট' ভি 8 টি আবর্জনা সংগ্রহকারীকে কঠোরভাবে চাপ দেবে, মুক্ত / পুনরায় ব্যবহারের জন্য আরও পুনরাবৃত্তি প্রয়োজন হবে। এটি আরও র‌্যাম ব্যবহার করবে। বেঞ্চকে অবশ্যই এই বিষয়গুলি বিবেচনায় নিতে হবে
  6. গুগল বন্ধ হ'ল পরিবর্তিত হবে ...

ভের এবং লেটের মধ্যে পারফরম্যান্স গ্যাপের প্রভাব বাস্তব জীবনের সম্পূর্ণ প্রোগ্রামে দেখা যায় এবং কোনও একক মৌলিক লুপে নয়।

যাইহোক, আপনাকে যেখানে করতে হবে না তা ব্যবহার করতে আপনার কোডটি কম পঠনযোগ্য করে তোলে।


আগ্রহের বাইরে - কোন তত্ত্বের letচেয়ে ধীর var? বিশেষ করে উপরের উত্তরে মন্তব্যগুলিতে theক্যমত্য দেওয়া তা দ্রুত দেখানো হচ্ছে?
জেমস আশ্চর্যডুড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.