ভি 8-তে এই কোড স্নিপেট ব্যবহার করার চেয়ে <= ধীর কেন?


166

আমি স্লাইডগুলি পড়ছি ভি 8 এর সাথে জাভাস্ক্রিপ্টের গতি সীমা ভেঙে , এবং নীচের কোডের মতো একটি উদাহরণ রয়েছে। আমি বুঝতে পারি না কেন এই ক্ষেত্রে <=তুলনায় ধীর <, কেউ কি এটি ব্যাখ্যা করতে পারেন? কোন মন্তব্য প্রশংসা করা হয়।

মন্থর:

this.isPrimeDivisible = function(candidate) {
    for (var i = 1; i <= this.prime_count; ++i) {
        if (candidate % this.primes[i] == 0) return true;
    }
    return false;
} 

(ইঙ্গিত: প্রাইমগুলি দৈর্ঘ্যের prime_count এর একটি অ্যারে)

দ্রুত:

this.isPrimeDivisible = function(candidate) {
    for (var i = 1; i < this.prime_count; ++i) {
        if (candidate % this.primes[i] == 0) return true;
    }
    return false;
} 

[আরও তথ্য] গতির উন্নতি তাৎপর্যপূর্ণ, আমার স্থানীয় পরিবেশ পরীক্ষায়, ফলাফলগুলি নিম্নরূপ:

V8 version 7.3.0 (candidate) 

মন্থর:

 time d8 prime.js
 287107
 12.71 user 
 0.05 system 
 0:12.84 elapsed 

দ্রুত:

time d8 prime.js
287107
1.82 user 
0.01 system 
0:01.84 elapsed

10
@ ড্যাক্রেডেনি তাত্ত্বিকভাবে এবং সমস্ত আধুনিক প্রসেসরের (এবং দোভাষী) উভয়ই প্রকৃত বাস্তবায়নের গণ্যগত অসুবিধা <=এবং <অভিন্ন।
টাইপিয়া

1
আমি দস্তাবেজটি পড়েছি, এমন একটি mainকোড রয়েছে যা সেই ফাংশনটিকে একটি লুপে কল করে যা 25000বার বার সঞ্চালিত হয়, সুতরাং আপনি সামগ্রিকভাবে এই পরিবর্তনটি করে অনেক কম পুনরাবৃত্তি করছেন। এছাড়াও, যদি অ্যারেটির দৈর্ঘ্য 5 থাকে তবে এটির চেষ্টা করা array[5]তার সীমা undefinedছাড়িয়ে যায় কারণ অ্যারেগুলি সূচীকরণ শুরু করে 0
শিডারজ

1
যদি এই প্রশ্নটি বোঝায় যে গতির উন্নতি কতখানি অর্জন করা হয় (উদাহরণস্বরূপ, 5 গুণ দ্রুত) যাতে লোকেরা অতিরিক্ত পুনরাবৃত্তি দ্বারা ছিটকে না যায়। আমি স্লাইডগুলিতে কত দ্রুত তা আবিষ্কার করার চেষ্টা করেছি কিন্তু অনেক ছিল এবং এটি খুঁজে পেতে আমার সমস্যা হয়েছিল, অন্যথায় আমি নিজেই এটি সম্পাদনা করব।
ক্যাপ্টেন ম্যান

@ ক্যাপিটম্যান আপনি ঠিক বলেছেন, স্লাইডগুলি থেকে সঠিক গতির উন্নতি করা শক্ত কারণ তারা একসাথে বেশ কয়েকটি বিভিন্ন বিষয় কভার করে। তবে এই আলাপের পরে স্পিকারের সাথে আমার কথোপকথনে, তিনি নিশ্চিত করেছেন যে এই পরীক্ষার ক্ষেত্রে অতিরিক্ত এক পুনরাবৃত্তি থেকে আপনি আশা করতে পারেন এটি কেবল শতাংশের একটি ক্ষুদ্র ক্ষুদ্র অংশ নয়, তবে একটি বড় পার্থক্য: বেশ কয়েক গুণ দ্রুত, সম্ভবত একটি আদেশ প্রস্থ বা আরও বেশি। এবং এর কারণ হ'ল ভি অ্যারে পিছনে পড়ে (বা সেই দিনগুলিতে ফিরে গিয়েছিল) ডি-অপ্টিমাইজড অ্যারে ফর্ম্যাটে ফিরে যখন আপনি অ্যারের সীমানার বাইরে পড়ার চেষ্টা করবেন।
মাইকেল গ্যারি

3
এটি ব্যবহার করে এমন কোনও সংস্করণ তুলনা করা কার্যকর হতে পারে <=তবে অন্যথায় এটি করে <সংস্করণটির সাথে অভিন্নরূপে কাজ করে i <= this.prime_count - 1। এটি "অতিরিক্ত পুনরাবৃত্তি" সমস্যা এবং "অ্যারের শেষের এক অতীত" উভয়ই সমাধান করে।
TheHansinator

উত্তর:


132

আমি গুগলে ভি 8 এ কাজ করি এবং বিদ্যমান উত্তর এবং মন্তব্যের শীর্ষে কিছু অতিরিক্ত অন্তর্দৃষ্টি দিতে চাই।

রেফারেন্সের জন্য, স্লাইডগুলি থেকে সম্পূর্ণ কোড উদাহরণ এখানে :

var iterations = 25000;

function Primes() {
  this.prime_count = 0;
  this.primes = new Array(iterations);
  this.getPrimeCount = function() { return this.prime_count; }
  this.getPrime = function(i) { return this.primes[i]; }
  this.addPrime = function(i) {
    this.primes[this.prime_count++] = i;
  }
  this.isPrimeDivisible = function(candidate) {
    for (var i = 1; i <= this.prime_count; ++i) {
      if ((candidate % this.primes[i]) == 0) return true;
    }
    return false;
  }
};

function main() {
  var p = new Primes();
  var c = 1;
  while (p.getPrimeCount() < iterations) {
    if (!p.isPrimeDivisible(c)) {
      p.addPrime(c);
    }
    c++;
  }
  console.log(p.getPrime(p.getPrimeCount() - 1));
}

main();

প্রথমত ও সর্বাগ্রে, কর্মক্ষমতা পার্থক্য সঙ্গে কিছুই করার আছে <এবং <=অপারেটরদের সরাসরি। সুতরাং দয়া করে কেবল <=আপনার কোড এড়ানোর জন্য হুপসের মধ্য দিয়ে ঝাঁপ দেবেন না কারণ আপনি স্ট্যাক ওভারফ্লোতে পড়েছেন যে এটি ধীর! --- তা নয়!


দ্বিতীয়ত, লোকেরা চিহ্নিত করল যে অ্যারেটি "হোলি"। এটি ওপির পোস্টের কোড স্নিপেট থেকে স্পষ্ট ছিল না, তবে আপনি কোডটি সূচনা করার সময় এটি স্পষ্ট করবেন this.primes:

this.primes = new Array(iterations);

ভি 8-তে অ্যারের উপাদানগুলির সাথে একটিHOLEY অ্যারের ফলাফল হয় , এমনকি যদি অ্যারে সম্পূর্ণরূপে ভরা / প্যাকড / সামঞ্জস্যপূর্ণ হয়। সাধারণভাবে, holey অ্যারে উপর অপারেশন বস্তাবন্দী অ্যারে উপর অপারেশন তুলনায় ধীর, কিন্তু এই ক্ষেত্রে পার্থক্য তুচ্ছ: এটি 1 টি অতিরিক্ত SMI (পরিমাণ ছোট পূর্ণসংখ্যা ) পরীক্ষা (প্রহরা গর্ত বিরুদ্ধে) প্রতিটি সময় আমরা আঘাত this.primes[i]মধ্যে লুপ isPrimeDivisible। কোন ব্যাপারই না!

টিএল; ডিআর অ্যারে থাকা HOLEYএখানে সমস্যা নয়।


অন্যরা উল্লেখ করেছিল যে কোডটি সীমানার বাইরে পড়ে। সাধারণত অ্যারেগুলির দৈর্ঘ্য ছাড়িয়ে পড়া এড়াতে বাঞ্ছনীয় এবং এই ক্ষেত্রে এটি কার্যকরীভাবে ব্যাপক হ্রাস এড়াতে পারে। তবে কেন? ভি 8 কেবলমাত্র একটি সামান্য পারফরম্যান্স প্রভাবের সাথে এই বাহ্যিক-সীমাবদ্ধ পরিস্থিতিতে কিছু পরিচালনা করতে পারে। এই বিশেষ ক্ষেত্রে এত বিশেষ কি?

সীমার বাইরে থাকা ফলাফলগুলি এই লাইনে this.primes[i]থাকার ফলে undefined:

if ((candidate % this.primes[i]) == 0) return true;

এবং এটি আমাদের আসল ইস্যুতে নিয়ে আসে : %অপারেটরটি এখন নন-ইন্টিজার অপারেন্ডগুলির সাথে ব্যবহৃত হচ্ছে!

  • integer % someOtherIntegerখুব দক্ষতার সাথে গণনা করা যেতে পারে; জাভাস্ক্রিপ্ট ইঞ্জিনগুলি এই ক্ষেত্রে উচ্চ-অনুকূলিত মেশিন কোড উত্পাদন করতে পারে।

  • integer % undefinedঅন্যদিকে একটি উপায় কম দক্ষতার পরিমাণ হিসাবে Float64Mod, যেহেতু undefinedএকটি ডাবল হিসাবে প্রতিনিধিত্ব করা হয়।

কোড স্নিপেট প্রকৃতপক্ষে পরিবর্তন করে উন্নত করা যায় <=বা <এই লাইনে:

for (var i = 1; i <= this.prime_count; ++i) {

... কারণ <=কোনওরকম তার চেয়ে উচ্চতর অপারেটর <নয়, কেবল কারণ এটি এই বিশেষ ক্ষেত্রে পড়া সীমার বাইরে এড়ায়।


1
মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
স্যামুয়েল লিউ

1
100% সম্পূর্ণ হতে, প্রিমেড ডিভিজিবলে এই.প্রাইমস [i] এর জন্য কীড লোড আইসি অপ্রত্যাশিতভাবে ভি 8-তে মেগামরফিক হয়। এটি বাগের মতো মনে হচ্ছে: বাগস.ক্রোমিয়াম.আর / পি / ভি 8/issues/detail?id=8561
ম্যাথিয়াস বাইনেস

226

অন্যান্য উত্তর এবং মন্তব্য উল্লেখ করে যে দুটি লুপের মধ্যে পার্থক্য হ'ল প্রথমটি দ্বিতীয়টির চেয়ে আরও একটি পুনরাবৃত্তি সম্পাদন করে। এটি সত্য, তবে 25,000 উপাদানগুলিতে বেড়ে ওঠা এমন একটি অ্যারেতে কম-বেশি এক পুনরাবৃত্তি কেবলমাত্র একটি ছোট পার্থক্য তৈরি করবে। বলপার্ক অনুমান হিসাবে, যদি আমরা এটির গড় দৈর্ঘ্যকে 12,500 হিসাবে ধরে নিই, তবে আমরা যে পার্থক্যটি আশা করতে পারি তা 1 / 12,500 বা মাত্র 0.008% এর কাছাকাছি হওয়া উচিত।

এখানে অতিরিক্ত পারফরম্যান্সের পারফরম্যান্সের পার্থক্যটি একটি অতিরিক্ত পুনরাবৃত্তির দ্বারা ব্যাখ্যা করার চেয়ে অনেক বড় এবং উপস্থাপনার শেষের দিকে সমস্যাটি ব্যাখ্যা করা হয়েছে।

this.primes একটি সংলগ্ন অ্যারে (প্রতিটি উপাদান একটি মান ধারণ করে) এবং উপাদানগুলি সমস্ত সংখ্যা।

একটি জাভাস্ক্রিপ্ট ইঞ্জিন এ জাতীয় অ্যারেটিকে সংখ্যার সমন্বয়যুক্ত এমন বস্তুর অ্যারের পরিবর্তে প্রকৃত সংখ্যাগুলির একটি সাধারণ অ্যারে হিসাবে অনুকূল করতে পারে তবে এতে অন্যান্য মান বা কোনও মান থাকতে পারে। অ্যাক্সেসের জন্য প্রথম ফর্ম্যাটটি আরও দ্রুত: এটিতে কম কোড লাগে এবং অ্যারেটি আরও ছোট তাই এটি ক্যাশে আরও ভাল ফিট করে। তবে কিছু শর্ত রয়েছে যা এই অনুকূলিত বিন্যাসটি ব্যবহার হতে বাধা দিতে পারে।

একটি শর্ত যদি কিছু অ্যারে উপাদান অনুপস্থিত থাকে। উদাহরণ স্বরূপ:

let array = [];
a[0] = 10;
a[2] = 20;

এখন এর মান কী a[1]? এটা তোলে কোন মূল্য আছে । (এটির মান রয়েছে তা বলাও ঠিক নয় undefined- মান যুক্ত একটি অ্যারের উপাদান undefinedসম্পূর্ণ অনুপস্থিত অ্যারে উপাদান থেকে পৃথক)

এটি কেবল সংখ্যার সাথে উপস্থাপন করার উপায় নেই, তাই জাভাস্ক্রিপ্ট ইঞ্জিনটি কম অপ্টিমাইজড ফর্ম্যাটটি ব্যবহার করতে বাধ্য হয়। যদি a[1]অন্য দুটি উপাদানগুলির মতো একটি সংখ্যাযুক্ত মান থাকে তবে অ্যারেটি কেবলমাত্র সংখ্যার অ্যারেটিতে অনুকূলিত হতে পারে।

একটি অ্যারে ডিওপিমাইজড ফর্ম্যাটে বাধ্য করার অন্য কারণ হ'ল যদি আপনি অ্যারের সীমানার বাইরে কোনও উপাদান অ্যাক্সেস করার চেষ্টা করেন, যেমন উপস্থাপনায় আলোচনা করা হয়েছে।

<=অ্যারের শেষের আগে একটি উপাদান পড়ার প্রচেষ্টা সহ প্রথম লুপ । অ্যালগরিদম এখনও সঠিকভাবে কাজ করে, কারণ শেষ অতিরিক্ত পুনরাবৃত্তিতে:

  • this.primes[i]মূল্যায়ন undefinedকারণ iঅ্যারে শেষ অতীত।
  • candidate % undefined(যে কোনও মানের জন্য candidate) এর মূল্যায়ন করে NaN
  • NaN == 0মূল্যায়ন false
  • সুতরাং, return trueকার্যকর করা হয় না।

সুতরাং এ যেন অতিরিক্ত পুনরাবৃত্তি কখনই ঘটে নি - বাকি যুক্তির উপর এর কোনও প্রভাব নেই। কোডটি অতিরিক্ত পুনরাবৃত্তি ছাড়াই একই ফলাফল তৈরি করে।

তবে সেখানে পৌঁছানোর জন্য, এটি অ্যারের শেষের আগে অস্তিত্বহীন উপাদান পড়ার চেষ্টা করেছিল। এটি অ্যারেটিকে অপ্টিমাইজেশনের বাইরে নিয়ে আসে - বা কমপক্ষে এই আলাপের সময়টি করেছিল।

<অ্যারের মধ্যে বিদ্যমান এমন উপাদানগুলি পড়ার সাথে দ্বিতীয় লুপটি তাই এটি একটি অনুকূলিত অ্যারে এবং কোডকে মঞ্জুরি দেয়।

সমস্যাটি আলাপের 90-91 পৃষ্ঠাগুলিতে বর্ণিত হয়েছে , তার আগে এবং তার পরে পৃষ্ঠাগুলিতে সম্পর্কিত আলোচনার সাথে।

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

ভি 8 লেখক যা বলেছিলেন তা যদি এখনও সত্য হয় তবে অ্যারের শেষের অতীত পড়লে এটি অনুকূলিত হওয়া থেকে বাধা পাবে এবং এটি ধীর বিন্যাসে ফিরে যেতে হবে।

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


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

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

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

3
@ বার্গি ভি 8 লেখক যিনি এই আলাপটি দিয়েছিলেন তিনি বলেছিলেন যে অ্যারের সীমানার বাইরে পড়ার চেষ্টা করার ফলে অ্যারেটি এমনভাবে মিশ্রিত হয় যে এটির মধ্যে এর মিশ্রণ রয়েছে: কেবলমাত্র অনুকূলিত নম্বর-বিন্যাসের পরিবর্তে এটি অ্যারেটিকে পুনরায় অপ্টিমাইজ করেছে জেনেরিক ফর্ম্যাট। অপ্টিমাইজড ক্ষেত্রে এটি সংখ্যার একটি সাধারণ অ্যারে হিসাবে আপনি কোনও সি প্রোগ্রামে ব্যবহার করতে পারেন। ডি-অপ্টিমাইজড ক্ষেত্রে এটি Valueঅবজেক্টগুলির একটি অ্যারে যা কোনও ধরণের মানগুলির রেফারেন্স ধরে রাখতে পারে। (আমি নাম প্রণীত Valueকিন্তু বিন্দু যে অ্যারে উপাদানের শুধু সহজ নম্বর নয় কিন্তু যে মোড়ানো সংখ্যা বা অন্যান্য ধরনের বস্তু।)
মাইকেল গিয়েরি

3
আমি ভি 8 তে কাজ করি। প্রশ্নের অ্যারে হিসাবে চিহ্নিত হবে HOLEYকারণ এটি ব্যবহার করে তৈরি করা হয়েছে new Array(n)(যদিও কোডের এই অংশটি ওপিতে দৃশ্যমান ছিল না)। HOLEYঅ্যারেগুলি HOLEYভি 8 এ চিরকালের জন্য থাকে , এমনকি পরে সেগুলি পূরণ করা হয়। এটি বলেছে, অ্যারে হোলি হওয়া এই ক্ষেত্রে পারফেক্ট ইস্যুর কারণ নয়; এর অর্থ কেবল প্রতিটি পুনরাবৃত্তির (গর্তের বিরুদ্ধে রক্ষা করার জন্য) অতিরিক্ত অতিরিক্ত স্মি চেক করতে হবে, এটি কোনও বড় বিষয় নয়।
ম্যাথিয়াস বাইনেন্স

19

TL; DR ধীর লুপটি অ্যারে 'আউট অফ সীমানা' অ্যাক্সেসের কারণে হয় যা ইঞ্জিনকে কম বা কোনও অপ্টিমাইজেশন সহ ফাংশনটি পুনরায় সংযোগ করতে বাধ্য করে বা এই অপ্টিমাইজেশানগুলির সাথে আরম্ভ করে ফাংশনটি সংকলন না করে ( যদি (JIT-) সংকলক প্রথম সংকলনের 'সংস্করণ' এর আগে এই শর্তটি সনাক্ত / সন্দেহ করে) তবে নীচে কেন পড়ুন;


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

উদাহরণ 1:
একটি Dense Array(সংলগ্ন হওয়া (সূচকগুলির মধ্যে কোনও ব্যবধানের মধ্যে নেই) এবং প্রকৃতপক্ষে প্রতিটি সূচকে একটি উপাদান) 0-ভিত্তিক সূচক (সর্বদা ES262 তে) ব্যবহার করে 5 টি উপাদান।

var arr_five_char=['a', 'b', 'c', 'd', 'e']; // arr_five_char.length === 5
//  indexes are:    0 ,  1 ,  2 ,  3 ,  4    // there is NO index number 5



সুতরাং আমরা সত্যিই <বনাম <=(বা 'একটি অতিরিক্ত পুনরাবৃত্তি') এর মধ্যে পারফরম্যান্স পার্থক্যের বিষয়ে কথা বলছি না , তবে আমরা কথা বলছি:
'সঠিক স্নিপেট (খ) ভুল স্নিপেট (ক) এর চেয়ে দ্রুত চালায় কেন?'

উত্তরটি হ'ল দ্বিগুণ (যদিও ES262 ভাষার প্রয়োগকারীের দৃষ্টিকোণ থেকে উভয়ই অনুকূলিতকরণের ফর্ম):

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

আইটেম 1 গ্রহণযোগ্য উত্তর দ্বারা যথেষ্ট (এবং সঠিকভাবে আইএমএইচও) ব্যাখ্যা করা হয়েছে , তবে এটি আইটেম 2: সংকলনে কেবল 2 শব্দ ('কোড') ব্যয় করে ।

আরও সুনির্দিষ্টভাবে: জেআইটি-সংকলন এবং আরও গুরুত্বপূর্ণভাবে জেআইটি- রে -সংকলন !

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

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

নিম্নলিখিত সাধারণ ফাংশনটি কল্পনা করুন:

function sum(arr){
  var r=0, i=0;
  for(;i<arr.length;) r+=arr[i++];
  return r;
}

পুরোপুরি পরিষ্কার, তাই না? কোনও অতিরিক্ত স্পষ্টকরণের দরকার নেই, তাই না? রিটার্ন টাইপ Numberঠিক আছে?
ঠিক আছে .. না, না এবং না ... এটি নামক ফাংশন প্যারামিটারে আপনি কী যুক্তি দিয়ে যাচ্ছেন তার উপর নির্ভর করে arr...

sum('abcde');   // String('0abcde')
sum([1,2,3]);   // Number(6)
sum([1,,3]);    // Number(NaN)
sum(['1',,3]);  // String('01undefined3')
sum([1,,'3']);  // String('NaN3')
sum([1,2,{valueOf:function(){return this.val}, val:6}]);  // Number(9)
var val=5; sum([1,2,{valueOf:function(){return val}}]);   // Number(8)

সমস্যা দেখুন? তারপরে বিবেচনা করুন এটি সবেমাত্র বিপুল সম্ভাব্য ক্রমানুসারে স্ক্র্যাপ করছে ... আমাদের এমনকি শেষ পর্যন্ত কী ধরণের TYPE ফাংশনটি রিটার্ন হয় তা আমরা জানি না ...

এখন এই একই ফাংশনটির কোডটি কল্পনা করুন - কোডটি আসলে বিভিন্ন ধরণের বা ইনপুট এমনকি বিভিন্ন প্রকারে ব্যবহৃত হচ্ছে, পুরোপুরি অক্ষরে অক্ষরে (উত্স কোডে) বর্ণিত এবং গতিশীলভাবে প্রোগ্রামে তৈরি 'অ্যারে' তৈরি করা হয়েছে ..

সুতরাং, আপনি যদি sumকেবলমাত্র কার্য সম্পাদনা করতে চান তবে একমাত্র উপায় যা সর্বদা যে কোনও এবং সমস্ত ধরণের ইনপুটটির জন্য নির্দিষ্ট-নির্দিষ্ট ফলাফলটি প্রদর্শন করে, স্পষ্টতই, কেবলমাত্র সমস্ত নির্দিষ্ট-নির্ধারিত প্রধান এবং উপ-পদক্ষেপগুলি সম্পাদন করে স্পষ্ট অনুসারে ফলাফলের গ্যারান্টি দিতে পারে (নামবিহীন প্রাক-y2k ব্রাউজারের মতো)। কোনও অপ্টিমাইজেশন নেই (কারণ কোনও অনুমান নয়) এবং মৃত ধীর ব্যাখ্যা করা স্ক্রিপ্টিং ভাষা অবশেষ।

জেআইটি-সংকলন (জাস্ট ইন টাইম হিসাবে জেআইটি) বর্তমান জনপ্রিয় সমাধান।

সুতরাং, আপনি ফাংশনটি এটি কী করে, রিটার্ন দেয় এবং গ্রহণ করে সে সম্পর্কে অনুমানগুলি ব্যবহার করে সংকলন শুরু করে।
আপনি যদি ফাংশনটি অন-স্পষ্ট সম্মতিসূচক ফলাফলগুলি (যেমন এটি অপ্রত্যাশিত ইনপুট গ্রহণ করে) প্রত্যাবর্তন শুরু করতে পারে তা সনাক্ত করতে যতটা সম্ভব চেক নিয়ে এসেছেন up তারপরে, পূর্ববর্তী সংকলিত ফলাফলটি টস করে আরও কিছু বিশদভাবে পুনরায় সংকলন করুন, ইতিমধ্যে আপনার যে আংশিক ফলাফল রয়েছে তা নিয়ে কী করবেন তা সিদ্ধান্ত নিন (নিশ্চিত হওয়ার জন্য এটি আবার বিশ্বাসযোগ্য বা গণনা করা বৈধ), প্রোগ্রামটিতে ফাংশনটি টাই করুন এবং আবার চেষ্টা কর. চূড়ান্তভাবে ধাপের দিকের স্ক্রিপ্ট-ব্যাখ্যায় ফিরে আসা spec

এই সব সময় লাগে!

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

দীর্ঘ গল্প সংক্ষিপ্ত: জাভাস্ক্রিপ্টের ভাষার শব্দার্থতত্ত্বগুলি প্রায়শই আমাদের পিছনে ফিরে আসে (যেমন ওপির উদাহরণে এই নীরব বাগের মতো) এর অর্থ এই নয় যে 'বোকা' ভুলগুলি দ্রুতগতিতে মেশিন-কোড ছিটিয়ে আমাদের সংকলকের সম্ভাবনা বাড়িয়ে তোলে। এটি ধরে নেওয়া হয় যে আমরা 'সাধারণত' সঠিক নির্দেশাবলী লিখেছিলাম: বর্তমান মন্ত্রটি আমরা 'ব্যবহারকারীদের' (প্রোগ্রামিং ভাষার) অবশ্যই থাকতে হবে: সংকলকটিকে সহায়তা করুন, আমরা কী চাই তা বর্ণনা করতে পারি, সাধারণ আইডিয়াগুলিকে সমর্থন করি (বেসিক বোঝার জন্য asm.js থেকে ইঙ্গিত নিন কি ব্রাউজারগুলি অপ্টিমাইজ করার চেষ্টা করতে পারে এবং কেন)।

এর কারণে, পারফরম্যান্সের বিষয়ে কথা বলা উভয়ই গুরুত্বপূর্ণ একটি খনি ক্ষেত্রের জন্য (এবং খনির ক্ষেত্রটি বলার কারণে আমি সত্যিই কিছু প্রাসঙ্গিক উপাদানকে নির্দেশ করে (এবং উদ্ধৃতি দিয়ে) শেষ করতে চাই:

অস্তিত্বের অবজেক্ট বৈশিষ্ট্যে অ্যাক্সেস এবং সীমা ছাড়িয়ে অ্যারে উপাদানগুলি undefinedব্যতিক্রম বাড়ানোর পরিবর্তে মান প্রদান করে returns এই গতিশীল বৈশিষ্ট্যগুলি জাভাস্ক্রিপ্টে প্রোগ্রামিংকে সুবিধাজনক করে তোলে তবে এগুলি জাভাস্ক্রিপ্টকে দক্ষ মেশিন কোডে সংকলন করতে অসুবিধাজনক করে তোলে।

...

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

উত্স:
"JITProf: pinpointing জে আই টি JIT-অনাত্মীয় জাভাস্ক্রিপ্ট কোড"
বার্কলে প্রকাশন, 2014, লিয়াং গং, মাইকেল Pradel, কৌশিক সেন
http://software-lab.org/publications/jitprof_tr_aug3_2014.pdf

ASM.JS (বাউন্ড অ্যারে অ্যাক্সেস বন্ধ পছন্দ করে না):

সামনের সময়ের সংকলন

যেহেতু asm.js জাভাস্ক্রিপ্টের একটি কঠোর উপসেট, এই স্পেসিফিকেশনটি কেবল বৈধতা যুক্তির সংজ্ঞা দেয় — কেবল কার্যকর জাভাস্ক্রিপ্টের শব্দার্থক শব্দটি se তবে, যাচাইযোগ্য asm.js সামনের সময়ের (এওটি) সংকলনের জন্য উপযুক্ত। তদুপরি, একটি এওটি সংকলক দ্বারা উত্পন্ন কোডটি যথেষ্ট দক্ষ হতে পারে, বৈশিষ্ট্যযুক্ত:

  • পূর্ণসংখ্যা এবং ভাসমান-পয়েন্ট সংখ্যাগুলির আনবক্সযুক্ত উপস্থাপনা;
  • রানটাইম টাইপ চেকের অনুপস্থিতি;
  • আবর্জনা সংগ্রহের অনুপস্থিতি; এবং
  • দক্ষ হিপ লোড এবং স্টোর (প্ল্যাটফর্মের দ্বারা পরিবর্তিতকরণের কৌশল সহ)

বৈধতা প্রমাণ করতে ব্যর্থ কোডটি অবশ্যই traditionalতিহ্যবাহী উপায়গুলি দ্বারা কার্যকর করাতে হবে, উদাহরণস্বরূপ, ব্যাখ্যা এবং / অথবা সুনির্দিষ্ট (জেআইটি) সংকলন।

http://asmjs.org/spec/latest/

এবং পরিশেষে https://blogs.windows.com/msedgedev/2015/05/07/bringing-asm-js-to-chakra-microsoft-edge/
এ সীমাগুলি অপসারণ করার সময় ইঞ্জিনের অভ্যন্তরীণ পারফরম্যান্সের উন্নতি সম্পর্কে একটি ছোট্ট সাবসেকশন রয়েছে চেক (কেবলমাত্র লুপের বাইরে সীমা-চেক তুলতে ইতিমধ্যে 40% এর উন্নতি হয়েছে)।



সম্পাদনা:
নোট করুন যে একাধিক উত্স বিভিন্ন স্তরের জেআইটি-সংশোধন নিয়ে ব্যাখ্যা পর্যন্ত আলোচনা করে।

ওপির স্নিপেট সম্পর্কিত উপরের তথ্যের ভিত্তিতে তাত্ত্বিক উদাহরণ :

  • #PrimeDivisible- এ কল করুন
  • সাধারণ অনুমান (যেমন সীমা অ্যাক্সেসের বাইরে না) ব্যবহার করে প্রাইমডিজিভিয়েলকে সঙ্কলন করুন
  • কাজ কর
  • বিএএম, হঠাৎ অ্যারে সীমা ছাড়িয়ে অ্যাক্সেস করে (শেষে ডানদিকে)।
  • ক্র্যাপ, ইঞ্জিন বলেছেন, আসুন এটি পুনরায় কম্পাইল করুন যা পৃথক (কম) অনুমানগুলি ব্যবহার করে প্রাইমডিজিবিলযোগ্য হয় এবং এই উদাহরণ ইঞ্জিনটি বর্তমান আংশিক ফলাফলটিকে পুনরায় ব্যবহার করতে পারে কিনা তা নির্ধারণের চেষ্টা করে না, তাই
  • ধীর ফাংশন ব্যবহার করে সমস্ত কাজ পুনরায় সাজান (আশা করি এটি শেষ হয়, অন্যথায় পুনরাবৃত্তি করুন এবং এবার কেবল কোডটি ব্যাখ্যা করুন)।
  • রিটার্ন ফলাফল

অতএব সময়টি ছিল:
প্রথম চালানো (শেষ পর্যন্ত ব্যর্থ হয়েছে) + প্রতিটি পুনরাবৃত্তির জন্য ধীর মেশিন কোড ব্যবহার করে পুনরায় সমস্ত কাজ করা + পুনরুদ্ধার ইত্যাদি .. স্পষ্টতই> এই তাত্ত্বিক উদাহরণে 2 গুণ বেশি সময় লাগে !



সম্পাদনা 2: (অস্বীকৃতি: নীচের তথ্যের উপর ভিত্তি করে অনুমান)
আমি যত বেশি মনে করি, ততই আমি মনে করি যে উত্তরটি ভ্রান্ত স্নিপেট এ (বা স্নিপেট বিতে পারফরম্যান্স-বোনাস) এর এই 'পেনাল্টি'র জন্য আরও প্রভাবশালী কারণটি ব্যাখ্যা করতে পারে , আপনি এটি কীভাবে ভাবেন তার উপর নির্ভর করে, অবিকল কেন আমি একে (স্নিপেট এ) প্রোগ্রামিং ত্রুটি বলার ক্ষেত্রে দৃ ad়ভাবে আছি:

এটি অনুমান করা বেশ লোভনীয় যে this.primesএটি একটি 'ঘন অ্যারে' খাঁটি সংখ্যাসূচক যেটি ছিল

  • সোর্স কোডে হার্ড-কোডেড আক্ষরিক ( কম্পাইল- টাইমের আগে কম্পাইলারের কাছে সমস্ত কিছু ইতিমধ্যে পরিচিত বলে 'সত্যিকারের' অ্যারে হয়ে উঠার জন্য পরিচিত অতিপ্রার্থ প্রার্থী ) বা
  • সম্ভবত new Array(/*size value*/)আরোহী ক্রমানুসারে একটি প্রাক-আকারের ( ) পূরনকারী একটি সংখ্যাসূচক ফাংশন ব্যবহার করে উত্পন্ন হয়েছে ('আসল' অ্যারে হওয়ার জন্য আরও দীর্ঘকালীন পরিচিত প্রার্থী)।

আমরা আরও জানি যে primesঅ্যারের দৈর্ঘ্যটি ক্যাশে করা হয়েছে prime_count! (এটি এর উদ্দেশ্য এবং নির্দিষ্ট আকার নির্দেশ করে)।

আমরা আরও জানি যে বেশিরভাগ ইঞ্জিন প্রাথমিকভাবে অ্যারেগুলিকে অনুলিপি-অন-সংশোধন (যখন প্রয়োজন হয়) হিসাবে পাস করে যা তাদের হ্যান্ডেলিংকে আরও দ্রুত করে তোলে (যদি আপনি এগুলি পরিবর্তন না করেন)।

সুতরাং এটি ধরে নেওয়া যুক্তিযুক্ত যে primesঅ্যারেটি ইতিমধ্যে অভ্যন্তরীণভাবে একটি অনুকূলিত অ্যারে যা সৃষ্টির পরে পরিবর্তিত হয় না (তৈরির পরে অ্যারে সংশোধন করার কোনও কোড না থাকলে সংকলকটির জন্য জানা সহজ) এবং তাই ইতিমধ্যে (যদি প্রয়োগ হয় তবে ইঞ্জিন) একটি অপ্টিমাইজড উপায়ে সঞ্চিত, বেশ কিছুটা যেমন এটি Typed Array

যেহেতু আমি আমার sumফাংশন উদাহরণ দিয়ে পরিষ্কার করার চেষ্টা করেছি , আর্গুমেন্ট (গুলি) যা উত্তীর্ণ হয়ে যায় আসলে কী ঘটবে তা প্রভাবিত করে এবং যেমন সেই নির্দিষ্ট কোডটি মেশিন-কোডে কীভাবে সংকলিত হচ্ছে। ফাংশনে একটি পাস Stringকরার ফলে sumস্ট্রিং পরিবর্তন করা উচিত নয় তবে কীভাবে ফাংশনটি জেআইটি-সংকলিত হয় তা পরিবর্তন করা উচিত! অ্যারে পাস করার sumজন্য মেশিন-কোডের সংস্করণটি আলাদা (সম্ভবত এই ধরণের এমনকি অতিরিক্ত, বা তারা যেমন ডাকবে তত 'আকৃতি') সংকলন করবে।

যেহেতু এটি সামান্য বোনকাস বলে মনে হচ্ছে টাইপড_আর্রে-এর মতো অ্যারেটিকে অন-দ্য ফ্লাইতে কিছু_এলসতে রূপান্তরিত করতে হবে যখন সংকলকটি primesজানে যে এই ফাংশনটি এটি পরিবর্তন করতেও যাচ্ছে না!

এই অনুমানের অধীনে 2 টি বিকল্প রয়েছে:

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

আমি এখন সত্যিই ভাবছি যে এটি 2 এর মধ্যে কোনটি!


2
অন্তর্নিহিত কিছু বিষয়ে একটি ভাল আলোচনা - তবে আপনি সবেই উত্তরটি একেবারে ব্যাখ্যা করেছেন (একেবারে শেষ বাক্যে)। খুব উপরে একটি টিএল; ড্র যোগ করতে পারেন? উদাহরণস্বরূপ "ধীর লুপটি সীমানা অ্যারে ছাড়িয়ে যাওয়ার কারণে যা ইঞ্জিনটিকে অপ্টিমাইজেশন ছাড়াই পুনরায় মূল্যায়ন করতে বাধ্য করে why কেন তা শিখতে পড়ুন" "
brichins

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

6

এটিতে কিছুটা বৈজ্ঞানিকতা যুক্ত করতে এখানে একটি জাসস্পিফ

https://jsperf.com/ints-values-in-out-of-array-bounds

এটি সীমানায় থাকাকালীন আর্টস এবং লুপিংয়ের সাথে পরিপূর্ণ একটি অ্যারে নিয়ন্ত্রণের ক্ষেত্রে পরীক্ষা করে। এটিতে 5 টি পরীক্ষার মামলা রয়েছে:

  • 1. সীমা ছাড়িয়ে লুপিং
  • 2. হোলি অ্যারে
  • ৩.এনএএনদের বিরুদ্ধে মডুলার গাণিতিক
  • ৪. সম্পূর্ণরূপে অপরিবর্তিত মান
  • 5. ব্যবহার ক new Array()

এটি দেখায় যে প্রথম 4 টি ক্ষেত্রে পারফরম্যান্সের জন্য সত্যিই খারাপ। সীমার বাইরে লুপিং অন্য 3 এর চেয়ে কিছুটা ভাল তবে সবগুলি 4 সবচেয়ে ভাল ক্ষেত্রেের চেয়ে 98% ধীর। কেস মাত্র কয়েক শতাংশ ধীর প্রায় কাঁচা অ্যারে হিসাবে ভাল হিসাবে হয়।
new Array()

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.