উত্তর:
জেআইটি সংকলকগণ তাদের কার্যকর করার ঠিক আগে বা এমনকি তারা ইতিমধ্যে কার্যকর করা অবস্থায়ও ফ্লাই কোডটি সংকলন করে। এই পদ্ধতিতে, কোডটি যে ভিএম চলছে সেগুলি কোড এক্সিকিউশনে নিদর্শনগুলি পরীক্ষা করতে পারে যাতে কেবলমাত্র রান-টাইমের তথ্য দিয়েই সম্ভব হয় optim তদুপরি, যদি ভিএম সিদ্ধান্ত নেয় যে সংমিত সংস্করণটি যে কোনও কারণে যথেষ্ট নয় (যেমন, অনেকগুলি ক্যাশে মিস করে, বা কোড প্রায়শই একটি বিশেষ ব্যতিক্রম ছুঁড়ে ফেলে) তবে এটি এটি অন্যরকমভাবে পুনরায় সংকলনের সিদ্ধান্ত নিতে পারে, যা অনেক বেশি স্মার্ট হতে পারে সংকলন।
অন্যদিকে, সি এবং সি ++ সংকলকগুলি traditionতিহ্যগতভাবে জেআইটি নয়। এগুলি কেবল একবার বিকাশকারীর মেশিনে একক শটে সংকলন করে এবং তারপরে একটি নির্বাহযোগ্য উত্পাদন হয় is
জেআইটি হ'ল ইন-টাইম সংকলনের জন্য সংক্ষিপ্ত, এবং নাম মিসন: রানটাইম চলাকালীন সময়ে এটি উপযুক্ত কোড অপটিমাইজেশন নির্ধারণ করে এবং সেগুলি প্রয়োগ করে। এটি সাধারণ সংকলকগুলি প্রতিস্থাপন করে না তবে দোভাষীদের অংশ। নোট করুন যে জাভা যেমন ইন্টারমিডিয়েট কোড ব্যবহার করে সেগুলির ভাষা উভয়ই রয়েছে : মধ্যবর্তী কোড অনুবাদ থেকে উত্সের জন্য একটি সাধারণ সংকলক এবং পারফরম্যান্স বৃদ্ধির জন্য দোভাষীর অন্তর্ভুক্ত একটি জেআইটি।
কোড অপটিমাইজেশন অবশ্যই "শাস্ত্রীয়" সংকলক দ্বারা সম্পাদন করা যেতে পারে, তবে মূল পার্থক্যটি লক্ষ্য করুন: জেআইটি সংকলকরা রানটাইমের সময় ডেটা ব্যবহার করতে পারে । এটি একটি বিশাল সুবিধা; এটি সঠিকভাবে শোষণ করা কঠিন হতে পারে, স্পষ্টতই।
উদাহরণস্বরূপ, কোডটি বিবেচনা করুন:
m(a : String, b : String, k : Int) {
val c : Int;
switch (k) {
case 0 : { c = 7; break; }
...
case 17 : { c = complicatedMethod(k, a+b); break; }
}
return a.length + b.length - c + 2*k;
}
একটি সাধারণ সংকলক এ সম্পর্কে খুব বেশি কিছু করতে পারে না। একটি জেআইটি সংকলক অবশ্য সনাক্ত করতে পারে যে m
এটি কেবল কখনও k==0
কোনও কারণে ডাকা হয়েছিল (সময়ের সাথে সাথে কোড পরিবর্তন হিসাবে এর মতো জিনিসগুলি ঘটতে পারে); এরপরে এটি কোডের একটি ছোট সংস্করণ তৈরি করতে পারে (এবং এটি স্থানীয় কোডে সংকলন করুন, যদিও আমি এটিকে একটি ছোট বিষয় হিসাবে ধারণা হিসাবে বিবেচনা করি):
m(a : String, b : String) {
return a.length + b.length - 7;
}
এই মুহুর্তে, এটি এখন তুচ্ছ হিসাবে সম্ভবত পদ্ধতি কলটি ইনলাইন করবে।
স্পষ্টতই, সান javac
জাভা 6 তে ব্যবহৃত বেশিরভাগ অপটিমাইজেশনকে বাতিল করে দিয়েছিল ; আমাকে বলা হয়েছে যে এই অপটিমাইজেশনগুলি জেআইটির পক্ষে অনেক কিছু করা শক্ত করেছে, এবং নির্লিপ্তভাবে সংকলিত কোডটি শেষ পর্যন্ত দ্রুত চলেছিল। চিত্রে যান.
m
কোনও সংস্করণ প্রতিস্থাপন করতে সক্ষম হবে না যা পরীক্ষা করে k
নি কারণ এটি প্রমাণ করতে সক্ষম m
হবে না যে এটি কখনও শূন্য নয় k
, তবে এটি প্রমাণ করতে সক্ষম হয় না যে এটি প্রতিস্থাপন করতে পারে এটা static miss_count; if (k==0) return a.length+b.length-7; else if (miss_count++ < 16) { ... unoptimized code for
মি ...} else { ... consider other optimizations...}
।
k=0
সর্বদা , যার অর্থ এটি ইনপুট বা পরিবেশের কোনও কাজ নয় তবে এটি পরীক্ষা বাদ দেওয়া কি নিরাপদ - তবে এটি নির্ধারণের জন্য স্থিতিশীল বিশ্লেষণ প্রয়োজন, যা খুব ব্যয়বহুল এবং এইভাবে সংকলনের সময় সাশ্রয়ী মূল্যের। কোনও জেআইটি জিততে পারে যখন কোডের ব্লকের মাধ্যমে একটি পাথ অন্যের তুলনায় অনেক বেশি সময় নেওয়া হয় এবং এই পথটির জন্য বিশেষ কোডটির একটি সংস্করণ আরও দ্রুত হবে। তবে দ্রুত পথটি প্রযোজ্য কিনা তা যাচাই করার জন্য এবং এখনও না হলে "ধীর পথ" গ্রহণের জন্য জেআইটি একটি পরীক্ষা ছাড়বে ।
Base* p
প্যারামিটার নেয় এবং এর মাধ্যমে ভার্চুয়াল ফাংশনগুলি কল করে; রানটাইম বিশ্লেষণ দেখায় যে প্রকৃত অবজেক্ট সর্বদা (বা প্রায় সর্বদা) নির্দেশিত বলে মনে হয় Derived1
type জেআইটি Derived1
পদ্ধতিতে স্ট্যাটিকালি সলভড (বা এমনকি ইনলাইনড) কল দিয়ে ফাংশনের একটি নতুন সংস্করণ তৈরি করতে পারে । এই কোডটি শর্তসাপেক্ষে পূর্বে থাকবে যা কিনা পরীক্ষা করে p
দেখবে যে এর vtable পয়েন্টারটি প্রত্যাশিত Derived1
টেবিলের দিকে নির্দেশ করে; যদি তা না হয় তবে তার পরিবর্তে ধীর গতি সম্পন্ন পদ্ধতি কলগুলির সাথে এটি ফাংশনের আসল সংস্করণে যায়।