মেশিন কোডে "সমস্ত উপায়ে" যাওয়ার পরিবর্তে একটি অন্তর্বর্তী বাইকোড (জাভা সহকারে) তৈরি করা সংকলনটি সাধারণত কম জটিলতায় জড়িত (এবং সম্ভবত সম্ভবত কম সময় নেয়)?
মেশিন কোডে "সমস্ত উপায়ে" যাওয়ার পরিবর্তে একটি অন্তর্বর্তী বাইকোড (জাভা সহকারে) তৈরি করা সংকলনটি সাধারণত কম জটিলতায় জড়িত (এবং সম্ভবত সম্ভবত কম সময় নেয়)?
উত্তর:
হ্যাঁ, জাভা বাইটকোডে সংকলন করা মেশিন কোডকে সংকলনের চেয়ে সহজ। এটি আংশিক কারণ লক্ষ্যমাত্রার জন্য কেবল একটি ফর্ম্যাট আছে (যেমন ম্যান্ড্রিল উল্লেখ করেছেন, যদিও এটি কেবল সংকলক জটিলতা হ্রাস করে, সময় সংকলন করে না), আংশিক কারণ জেভিএম অনেক সহজ মেশিন এবং বাস্তব সিপিইউগুলির তুলনায় প্রোগ্রাম করার জন্য আরও সুবিধাজনক - কারণ এটি নকশা করা হয়েছে জাভা ভাষার সাথে তাল মিলিয়ে বেশিরভাগ জাভা অপারেশন খুব সাধারণ উপায়ে ঠিক একটি বাইটকোড অপারেশনে ম্যাপ করে। আর একটি খুব গুরুত্বপূর্ণ কারণ হ'ল কার্যত না noঅপ্টিমাইজেশন স্থান নেয়। প্রায় সমস্ত দক্ষতার উদ্বেগগুলি জেআইটি সংকলক (বা সামগ্রিকভাবে জেভিএম) তে রেখে যায়, তাই সাধারণ সংকলকগুলির পুরো মাঝারি প্রান্তটি অদৃশ্য হয়ে যায়। এটি মূলত একবার এএসটি দিয়ে যেতে পারে এবং প্রতিটি নোডের জন্য তৈরি বাইকোড সিকোয়েন্স তৈরি করতে পারে। উত্পাদনের পদ্ধতির টেবিল, ধ্রুবক পুল ইত্যাদির কিছু "প্রশাসনিক ওভারহেড" রয়েছে তবে এটি এলএলভিএম এর জটিলতার সাথে তুলনা করে কিছুই নয়।
একটি সংকলক হ'ল এমন একটি প্রোগ্রাম যা মানব-পঠনযোগ্য 1 টি পাঠ্য ফাইল নেয় এবং মেশিনের বাইনারি নির্দেশিকায় তাদের অনুবাদ করে। আপনি যদি কোনও পদক্ষেপ পিছনে নিয়ে যান এবং এই তাত্ত্বিক দৃষ্টিকোণ থেকে আপনার প্রশ্নটি সম্পর্কে চিন্তা করেন, জটিলতা প্রায় একই রকম। তবে আরও ব্যবহারিক স্তরে, বাইট কোড সংকলকগুলি সহজ।
একটি প্রোগ্রাম সংকলনের জন্য কোন বিস্তৃত পদক্ষেপগুলি ঘটতে হবে?
দুজনের মধ্যে মাত্র দুটি বাস্তব পার্থক্য রয়েছে।
সাধারণভাবে, একাধিক সংকলন ইউনিট সহ একটি প্রোগ্রামের জন্য মেশিন কোডে সংকলন করার সময় লিঙ্ক করা প্রয়োজন এবং সাধারণত বাইট কোডের সাথে হয় না। লিঙ্কিং এই প্রশ্নের প্রসঙ্গে সংকলনের অংশ কিনা তা নিয়ে কেশ বিভক্ত হতে পারে। যদি তা হয় তবে বাইট কোড সংকলনটি কিছুটা সহজ হবে। যাইহোক, লিঙ্কিংয়ের জটিলতা রান-টাইমে তৈরি করা হয় যখন লিঙ্কের অনেকগুলি উদ্বেগ ভিএম দ্বারা পরিচালিত হয় (নীচে আমার নোটটি দেখুন)।
বাইট কোড সংকলকরা ততটা অপ্টিমাইজ করতে চান না কারণ ভিএম ফ্লাইতে এটি আরও ভাল করতে পারে (আজকাল ভিএমএসের তুলনায় জেআইটি সংকলকগুলি মোটামুটি স্ট্যান্ডার্ড সংযোজন)।
এ থেকে আমি উপসংহারে পৌঁছেছি যে বাইট কোড সংকলকগুলি সবচেয়ে অপ্টিমাইজেশনের জটিলতা এবং সমস্ত লিঙ্কিংকে বাদ দিতে পারে, উভয়কে ভিএম রানটাইমের সাথে পিছনে ফেলে। বাইট কোড সংকলকগুলি অনুশীলনে সহজ কারণ তারা মেশিন কোড সংকলকরা নিজেরাই গ্রহণ করে এমন অনেক জটিলতা ভিএম-তে স্থান করে দেয়।
1 গুপ্ত ভাষা গণনা করা হয় না
আমি বলব যে সংকলনটি সর্বদা জাভাতে জেনেরিক ভার্চুয়াল মেশিন কোডে জাভা হয় তাই সংকলক নকশাটি সহজ করে। এর অর্থ হ'ল আপনাকে একবার কোডটি সংকলন করতে হবে এবং এটি কোনও প্লাটফর্মে চলবে (প্রতিটি মেশিনে সংকলন না করে)। সংকলনের সময়টি কম হবে কিনা তা আমি নিশ্চিত নই কারণ আপনি ভার্চুয়াল মেশিনটিকে একটি প্রমিত মেশিনের মতো বিবেচনা করতে পারেন।
অন্যদিকে, প্রতিটি মেশিনে জাভা ভার্চুয়াল মেশিনটি লোড করতে হবে যাতে এটি "বাইট কোড" (যা জাভা কোড সংকলনের ফলে ভার্চুয়াল মেশিন কোড) ব্যাখ্যা করতে পারে, এটি প্রকৃত মেশিন কোডে অনুবাদ করে চালাতে পারে ।
ইমো এটি খুব বড় প্রোগ্রামগুলির পক্ষে ভাল তবে ছোটগুলির পক্ষে খুব খারাপ (কারণ ভার্চুয়াল মেশিনটি স্মৃতিশক্তি নষ্ট করে)।
সংকলনের জটিলতা মূলত উত্স ভাষা এবং লক্ষ্য ভাষা এবং এই ব্যবধানটি কমিয়ে আনার সময় আপনি প্রয়োগ করতে চান এমন অপ্টিমাইজেশনের স্তরের মধ্যে শব্দার্থক ব্যবধানের উপর নির্ভর করে।
উদাহরণস্বরূপ, জাভা সোর্স কোডটি জেভিএম বাইট কোডে সংকলন করা তুলনামূলকভাবে সোজা এগিয়ে রয়েছে, যেহেতু জাভা-র একটি মূল উপসেট রয়েছে যা জেভিএম বাইট কোডের একটি উপসেটে সরাসরি ম্যাপ করে। কিছু পার্থক্য রয়েছে: জাভার লুপ রয়েছে তবে না GOTO
, জেভিএমের GOTO
তবে লুপ নেই, জাভাতে জেনেরিক রয়েছে, জেভিএম নেই তবে সেগুলি সহজেই মোকাবিলা করা যায় (লুপগুলি থেকে শর্তসাপেক্ষ জাম্পে রূপান্তর তুচ্ছ, টাইপ ক্ষয়টি কিছুটা কম) সুতরাং, তবে এখনও পরিচালনাযোগ্য)। অন্যান্য পার্থক্য রয়েছে তবে কম তীব্র।
রুবি সোর্স কোডটি জেভিএম বাইট কোডটি সংকলন করা অনেক বেশি জড়িত (বিশেষত এর আগে invokedynamic
এবং MethodHandles
জাভা in তে প্রবর্তিত হয়েছিল, বা আরও স্পষ্টভাবে জেভিএম স্পেকের তৃতীয় সংস্করণে)। রুবিতে, রানটাইমগুলিতে পদ্ধতিগুলি প্রতিস্থাপন করা যেতে পারে। জেভিএম-তে, রানটাইমের সময় প্রতিস্থাপন করা যায় এমন কোডের ক্ষুদ্রতম ইউনিটটি একটি শ্রেণি, সুতরাং রুবি পদ্ধতিগুলি জেভিএম পদ্ধতিতে নয়, জেভিএম ক্লাসগুলিতে সংকলন করতে হয়। রুবি পদ্ধতির প্রেরণটি জেভিএম পদ্ধতি প্রেরণের সাথে মেলে না এবং এর আগে invokedynamic
, জেভিএম- তে আপনার নিজস্ব পদ্ধতি প্রেরণ প্রক্রিয়াটি ইনজেক্ট করার কোনও উপায় ছিল না। রুবির ধারাবাহিকতা এবং কর্টিন রয়েছে তবে জেভিএম সেগুলি বাস্তবায়নের জন্য সুবিধার অভাব রয়েছে। (জেভিএম এর)GOTO
পদ্ধতির মধ্যে লক্ষ্যমাত্রা লাফাতে সীমাবদ্ধ)) জেভিএমের একমাত্র নিয়ন্ত্রণ প্রবাহ আদিম, এটি ধারাবাহিকতা বাস্তবায়নের পক্ষে যথেষ্ট শক্তিশালী হবে ব্যতিক্রমগুলি এবং করটিইন থ্রেডগুলি প্রয়োগ করা, উভয়ই অত্যন্ত ভারী ওজনযুক্ত, যেখানে কর্টিনগুলির পুরো উদ্দেশ্যটি হ'ল খুব হালকা হতে হবে।
ওটিওএইচ, রুবিনিয়াস বাইট কোড বা ইয়ারভি বাইট কোডে রুবি সোর্স কোডটি সংকলন করা আবার তুচ্ছ, কারণ এই দু'টিই স্পষ্টরূপে রুবির সংকলন লক্ষ্য হিসাবে তৈরি করা হয়েছে (যদিও রুবিনিয়াস অন্যান্য ভাষার জন্য যেমন কফিস্ক্রিপ্ট এবং সবচেয়ে বিখ্যাত ফ্যানসি ব্যবহার করেছেন) ।
তেমনি, জেভিএম বাইট কোডে x86 নেটিভ কোডটি সংকলন সোজা-ফরোয়ার্ড নয়, আবারও, একটি দুর্দান্ত বৃহত শব্দার্থক ব্যবধান রয়েছে।
হাস্কেল আরেকটি ভাল উদাহরণ: হাস্কেলের সাথে একাধিক উচ্চ-কর্মক্ষমতা, শিল্প শক্তি উত্পাদনের জন্য প্রস্তুত সংকলক রয়েছে যা নেটিভ x86 মেশিন কোড তৈরি করে, তবে আজ অবধি, জেভিএম বা সিএলআইয়ের জন্য কোনও কার্যকরী সংকলক নেই, কারণ শব্দার্থক ফাঁকটি এত বড় যে এটি ব্রিজ করা খুব জটিল। সুতরাং, এটি একটি উদাহরণ যেখানে নেটিভ মেশিন কোডে সংকলন জেভিএম বা সিআইএল বাইট কোড সংকলনের চেয়ে কম জটিল। এর কারণ নেটিভ মেশিন কোডের অনেক নিম্ন স্তরের আদিম (( GOTO
পয়েন্টার,…) রয়েছে যা পদ্ধতি কল বা ব্যতিক্রমের মতো উচ্চ স্তরের আদিম ব্যবহারের চেয়ে আপনি যা চান তা করতে "জোর করে" আরও সহজ হতে পারে।
সুতরাং, কেউ বলতে পারেন যে উচ্চতর স্তরের টার্গেট ল্যাঙ্গুয়েজ, সংকলকটির জটিলতা হ্রাস করার জন্য এটি উত্স ভাষার শব্দার্থবিদ্যার সাথে আরও ঘনিষ্ঠভাবে মিলতে হবে।
অনুশীলনে, বর্তমানে বেশিরভাগ জেভিএম খুব জটিল সফ্টওয়্যার, জেআইটি সংকলন করছে (সুতরাং বাইটোকডটি জেভিএম দ্বারা মেশিন কোডে গতিশীলভাবে অনুবাদ করা হয়েছে)।
সুতরাং জাভা উত্স কোড (বা ক্লোজার সোর্স কোড) থেকে জেভিএম বাইট কোডের সংকলনটি সত্যই সহজ হলেও, জেভিএম নিজেই মেশিন কোডে জটিল অনুবাদ করছে।
জেভিএম-এর অভ্যন্তরে এই জেআইটি অনুবাদটি গতিশীল হওয়ার বিষয়টি জেভিএমকে বাইটকোডের সর্বাধিক প্রাসঙ্গিক অংশগুলিতে ফোকাস করতে সক্ষম করে। ব্যবহারিকভাবে বলতে গেলে, বেশিরভাগ জেভিএম জেভিএম বাইটকোডের আরও হটেস্ট অংশগুলি (যেমন সর্বাধিক পরিচিত পদ্ধতিগুলি, বা সর্বাধিক সম্পাদিত বেসিক ব্লক) অনুকূল করে তোলে।
আমি নিশ্চিত নই যে জেভিএম + জাভার বাইকোড সংকলক থেকে সম্মিলিত জটিলতা সামনের সময়ের সংকলকগুলির জটিলতার চেয়ে উল্লেখযোগ্যভাবে কম।
আরও লক্ষ করুন যে বেশিরভাগ traditionalতিহ্যবাহী সংকলক (যেমন জিসিসি বা ক্ল্যাং / এলএলভিএম ) ইনপুট সি (বা সি ++, বা অ্যাডা, ...) উত্স কোডটিকে অভ্যন্তরীণ উপস্থাপনায় রূপান্তর করছে ( জিমিসির জন্য জিম্পল, ক্ল্যাংয়ের জন্য এলএলভিএম ) যা একেবারে অনুরূপ কিছু বাইকোড তারপরে তারা সেই অভ্যন্তরীণ উপস্থাপনাগুলি (প্রথমে এটি নিজের মধ্যে অনুকূল করে তোলা, অর্থাত্ বেশিরভাগ জিসিসি অপ্টিমাইজেশন পাসগুলি জিম্পলকে ইনপুট হিসাবে গ্রহণ করছে এবং জিম্পলকে আউটপুট হিসাবে উত্পাদন করছে; পরে এটি থেকে এসেম্বলার বা মেশিন কোড নির্গমন করছে) অবজেক্ট কোডে।
বিটিডাব্লু , সাম্প্রতিক জিসিসি (উল্লেখযোগ্যভাবে libgccjit ) এবং LLVM অবকাঠামো সহ আপনি তাদের অন্য কিছু (বা আপনার নিজের) ভাষা তাদের অভ্যন্তরীণ জিম্পল বা এলএলভিএম উপস্থাপনায় সংকলন করতে ব্যবহার করতে পারেন, তারপরে মাঝের প্রান্তের অনেকগুলি অপ্টিমাইজেশন ক্ষমতা থেকে লাভ এবং পিছনে- এই সংকলকগুলির শেষ অংশগুলি।