কেন জাভা এপিআই শর্ট বা বাইটের পরিবর্তে ইনট ব্যবহার করে?


137

জাভা এপিআই কেন ব্যবহার করবে int, কখন shortবা এমনকি byteযথেষ্ট হবে?

উদাহরণ: DAY_OF_WEEKক্লাসের ক্ষেত্রগুলি Calendarব্যবহার করে int

পার্থক্যটি যদি খুব ন্যূনতম হয় তবে কেন এই ডেটাটাইপগুলি ( short, int) মোটেই বিদ্যমান?

উত্তর:


166

ইতিমধ্যে কয়েকটি কারণ উল্লেখ করা হয়েছে। উদাহরণ হিসেবে বলা যায় যে, আসলে "... (প্রায়) বাইট সকল অপারেশন, সংক্ষিপ্ত int- এ এই প্রিমিটিভের প্রচার হবে" । যাইহোক, সুস্পষ্ট পরবর্তী প্রশ্নটি হবে: কেন এই ধরণের পদোন্নতি দেওয়া হয় int?

সুতরাং এক স্তর আরও গভীরতর: উত্তরটি সম্ভবত জাভা ভার্চুয়াল মেশিন নির্দেশ সেট সম্পর্কিত হতে পারে। জাভা ভার্চুয়াল মেশিন স্পেসিফিকেশনের টেবিলের সংক্ষিপ্তসার হিসাবে , সমস্ত অবিচ্ছেদ্য পাটিগণিত ক্রিয়াকলাপ যেমন সংযোজন, বিভাজন এবং অন্যান্যগুলি কেবল প্রকার intএবং প্রকারের জন্য উপলব্ধ long, তবে ছোট প্রকারের জন্য নয়

(সরাইয়া একটি: ছোট প্রকার ( byteএবং short) মূলত শুধুমাত্র উদ্দেশ্যে হয় অ্যারে একটি। অ্যারে মত new byte[1000]1000 বাইট নিতে হবে এবং অন্য কোনো একটি অ্যারের new int[1000]4000 বাইট লাগবে)

এখন, অবশ্যই কেউ বলতে পারেন যে "... সুস্পষ্ট পরবর্তী প্রশ্নটি হবে: এই নির্দেশাবলী কেন কেবল int(এবং long) জন্য দেওয়া হয় ?"

উপরে উল্লিখিত জেভিএম বিশেষে একটি কারণ উল্লেখ করা হয়েছে:

প্রতিটি টাইপ করা নির্দেশাবলী যদি জাভা ভার্চুয়াল মেশিনের রান-টাইম ডেটা ধরণের সমস্তকে সমর্থন করে তবে বাইটে উপস্থাপন করার চেয়ে আরও বেশি নির্দেশাবলী থাকতে পারে

অতিরিক্তভাবে, জাভা ভার্চুয়াল মেশিনকে একটি বাস্তব প্রসেসরের বিমূর্ততা হিসাবে বিবেচনা করা যেতে পারে। এবং ছোট ধরণের জন্য ডেডিকেটেড এরিথমেটিক লজিক ইউনিট প্রবর্তন করা প্রচেষ্টাটির পক্ষে উপযুক্ত হবে না: এটির জন্য অতিরিক্ত ট্রানজিস্টর প্রয়োজন হবে, তবে এটি কেবল একটি ঘড়ির চক্রে একটি সংযোজন সম্পাদন করতে পারে। যখন জেভিএম ডিজাইন করা হয়েছিল তখন প্রভাবশালী আর্কিটেকচারটি 32 বাইট ছিল ঠিক একটি 32 বিটের জন্য int। (Bit৪ বিট longমান সহ যে ক্রিয়াকলাপগুলি বিশেষ কেস হিসাবে প্রয়োগ করা হয়)।

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


সম্পাদনা: একটি সংক্ষিপ্ত সংযোজন, প্রশ্ন থেকে উদাহরণের দিকে দৃষ্টি নিবদ্ধ করে, তবে আরও সাধারণ অর্থে: কেউ আরও জিজ্ঞাসা করতে পারে যে ছোট প্রকারগুলি ব্যবহার করে ক্ষেত্রগুলি সংরক্ষণ করা সুবিধাজনক হবে না কিনা । উদাহরণস্বরূপ, কেউ ভাবতে পারেন যে এ Calendar.DAY_OF_WEEKহিসাবে সংরক্ষণ করে স্মৃতি সংরক্ষণ করা যেতে পারে byte। তবে এখানে, জাভা ক্লাস ফাইল ফর্ম্যাট খেলতে আসে: একটি ক্লাস ফাইলের সমস্ত ক্ষেত্রগুলি কমপক্ষে একটি "স্লট" দখল করে, যার আকার একটি int(32 বিট) থাকে। ("প্রশস্ত" ক্ষেত্র doubleএবং longদুটি স্লট দখল করে)। সুতরাং স্পষ্টভাবে কোনও ক্ষেত্র হিসাবে ঘোষণা করে shortবা byteকোনও স্মৃতি সংরক্ষণ করবে না।


আমি অনুমান করব যে অপারেটসগুলিকে কেন ইনট হিসাবে প্রচার করা হয় তার যুক্তিটিও সি এবং সি ++ এ
শফিক ইয়াঘমোর

@ মার্কো 13 "সুতরাং স্পষ্টভাবে কোনও ক্ষেত্রকে সংক্ষিপ্ত বা বাইট হিসাবে ঘোষণা করা কোনও স্মৃতিও বাঁচাতে পারে না।" এটা কি সত্যি? আমি এটা সঠিক মনে করি না।
এসিভি

@ACV কড়া কথায় বলতে গেলে, একটি বাস্তবায়ন আরও কমপ্যাক্ট ফর্ম সংরক্ষণ করতে বেছে নিতে পারে, তবে "ভার্চুয়াল" (অর্থাৎ ভার্চুয়াল মেশিন দ্বারা) যে ফর্ম্যাটটি উদ্ভাসিত হয়েছে তা মানকে কমপক্ষে আকার হিসাবে গণ্য করবে int। আপনার যদি অন্য কোনও প্রয়োগের রেফারেন্স থাকে তবে আমি উত্তরটি আপডেট করব এবং সেই অনুযায়ী লিঙ্কটি সন্নিবেশ করবো।
মার্কো 13

40

(প্রায়) সকল অপারেশন byte, shortতাদের প্রচার হবে int, উদাহরণস্বরূপ, আপনি লিখতে পারেন:

short x = 1;
short y = 2;

short z = x + y; //error

গাণিতিকগুলি ব্যবহার করার সময় সহজ এবং সোজা intহয়, castালার প্রয়োজন হয় না।

স্থানের ক্ষেত্রে এটি খুব সামান্য পার্থক্য করে। byteএবং shortজিনিসগুলিকে জটিল করে তুলবে, আমি মনে করি না যে এই মাইক্রো অপ্টিমাইজেশন এটির পক্ষে মূল্যবান নয় কারণ আমরা একটি নির্দিষ্ট পরিমাণে ভেরিয়েবলের কথা বলছি।

byteআপনি এম্বেড থাকা ডিভাইসগুলির জন্য বা ফাইল / নেটওয়ার্কগুলির সাথে ডিল করার সময় প্রোগ্রামটি প্রাসঙ্গিক এবং দরকারী। এছাড়াও এই আদিমগুলি সীমাবদ্ধ, ভবিষ্যতে যদি গণনাগুলি তাদের সীমা অতিক্রম করতে পারে? Calendarশ্রেণীর জন্য এমন একটি এক্সটেনশান সম্পর্কে চিন্তা করার চেষ্টা করুন যা বড় সংখ্যায় বিকশিত হতে পারে।

এছাড়াও মনে রাখবেন 64-বিট প্রসেসর, স্থানীয়দের রেজিস্টার সংরক্ষিত হবে এবং কোন সম্পদ ব্যবহার করবে না, তাই ব্যবহার int, shortএবং অন্যান্য প্রিমিটিভের একেবারেই কোনও পার্থক্য করতে হবে না। তদুপরি, অনেক জাভা প্রয়োগগুলি ভেরিয়েবল * (এবং অবজেক্টস) সারিবদ্ধ করে ।


* byte এবং shortএকই স্থানটি দখল করুন যেমন intতারা স্থানীয় ভেরিয়েবল, বর্গ ভেরিয়েবল বা এমনকি উদাহরণ ভেরিয়েবল। কেন? কারণ (বেশিরভাগ) কম্পিউটার সিস্টেমে, ভেরিয়েবলের ঠিকানাগুলি সারিবদ্ধ হয় , সুতরাং উদাহরণস্বরূপ আপনি যদি একটি একক বাইট ব্যবহার করেন, আপনি আসলে দুটি বাইট ব্যবহার করবেন - একটি ভেরিয়েবলের জন্য এবং অন্যটি প্যাডিংয়ের জন্য।

অন্যদিকে অ্যারেতে, byte1 বাইট নিন, short2 বাইট নিন এবং intচারটি বাইট নিন, কারণ অ্যারেগুলিতে কেবল শুরু এবং সম্ভবত এর প্রান্তটি সারিবদ্ধ হতে হবে। আপনি যেমন ব্যবহার করতে চান তার ক্ষেত্রে এটি একটি পার্থক্য তৈরি করবে, উদাহরণস্বরূপ System.arraycopy(), তাহলে আপনি সত্যিকার অর্থে পারফরম্যান্সের পার্থক্যটি লক্ষ্য করবেন।


1
মজাদার ঘটনা: আপনি যদি উভয় মানের জন্য চূড়ান্ত সংশোধক ব্যবহার করেন তবে এটি কার্যকর হবে। :)
আলেকজান্ডার

7

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

short month = Calendar.JUNE;
month = month + (short) 1; // is july

সুস্পষ্ট কাস্টিং লক্ষ করুন। সংক্ষিপ্ত মানগুলি intযখন গাণিতিক ক্রিয়াকলাপে ব্যবহৃত হয় তখন স্পষ্টভাবে মানগুলিতে উন্নীত হয় । (অপারেন্ড স্ট্যাকের উপর, শর্টসগুলি এমনকি ints হিসাবে প্রকাশ করা হয়)) এটি ব্যবহার করা বেশ জটিল হবে। এজন্য intধ্রুবকগুলির জন্য মানগুলি প্রায়শই পছন্দ করা হয়।

তার তুলনায়, স্টোরেজ দক্ষতার লাভটি ন্যূনতম কারণ সেখানে কেবলমাত্র এই ধরণের ধ্রুবকের একটি নির্দিষ্ট সংখ্যক উপস্থিত রয়েছে। আমরা 40 ধ্রুবক সম্পর্কে কথা বলছি। থেকে তাদের স্টোরেজ পরিবর্তন intকরা shortআপনাকে নিরাপদ করবে 40 * 16 bit = 80 byte। আরও রেফারেন্সের জন্য এই উত্তর দেখুন ।


5

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

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

উপকারিতা এবং মতামতগুলি ওজন করা খুব সহজ: এটি একটি খারাপ দর্শন।


4

ভার্চুয়াল মেশিনের ডিজাইন জটিলতা এটি কত ধরণের ক্রিয়াকলাপ সম্পাদন করতে পারে তার একটি ফাংশন। "মাল্টিপাল" - এর মতো কোনও নির্দেশনার চারটি বাস্তবায়ন করা সহজ - 32-বিট পূর্ণসংখ্যার জন্য প্রত্যেকে, 64-বিট ইন্টিজার, 32-বিট ফ্লোটিং-পয়েন্ট এবং 64-বিট ফ্লোটিং-পয়েন্ট - এর চেয়ে আরও উপরের দিকে, ছোট সংখ্যার ধরণের সংস্করণগুলিও। আরও আকর্ষণীয় নকশার প্রশ্ন হ'ল কম কেন than৪ প্রকারের চেয়ে চার ধরণের হওয়া উচিত (64৪-বিট ইন্টিজার সহ সমস্ত সংখ্যার গণনা সম্পাদন করা এবং / অথবা 64৪-বিট ভাসমান-পয়েন্ট মান সহ সমস্ত ভাসমান-পয়েন্ট গণনা করা)। ৩২-বিট পূর্ণসংখ্যার ব্যবহারের কারণটি হ'ল জাভা অনেকগুলি প্ল্যাটফর্মে চালিত হবে বলে আশা করা হয়েছিল যেখানে -২-বিট প্রকারের সাথে দ্রুত 16-বিট বা 8-বিট ধরণের কাজ করা যেতে পারে, তবে 64৪-বিট প্রকারের ক্রিয়াকলাপ লক্ষণীয় হবে ধীর।শুধুমাত্র 32-বিট প্রকারের।

32-বিট মানগুলিতে ভাসমান-পয়েন্ট গণনা সম্পাদনের ক্ষেত্রে, সুবিধাগুলি কিছুটা কম স্পষ্ট। কিছু প্ল্যাটফর্ম রয়েছে যেখানে একটি গণনা পছন্দ করেfloat a=b+c+d;সমস্ত অপারেন্ডকে একটি উচ্চ-নির্ভুলতার ধরণের রূপান্তর করে, সংযুক্ত করে এবং তারপরে ফলাফলটিকে স্টোরেজের জন্য 32-বিট ভাসমান-পয়েন্ট নম্বরে রূপান্তর করে খুব দ্রুত সম্পাদন করা যেতে পারে। অন্যান্য প্ল্যাটফর্মগুলি রয়েছে যেখানে 32 বিট ভাসমান-পয়েন্ট মান ব্যবহার করে সমস্ত গণনা সম্পাদন করা আরও দক্ষ হবে। জাভা এর নির্মাতারা সিদ্ধান্ত নিয়েছিলেন যে সমস্ত প্ল্যাটফর্মগুলি একইভাবে কাজ করা উচিত এবং যে হার্ডওয়্যার প্ল্যাটফর্মগুলির জন্য তাদের পক্ষে সমর্থন করা উচিত যার জন্য 32-বিট ভাসমান-পয়েন্ট গণনাগুলি দীর্ঘতরগুলির চেয়ে দ্রুততর হয়, যদিও এই পিসি উভয়ই গতির মারাত্মকভাবে হ্রাস পেয়েছে এবং একটি সাধারণ পিসিতে ভাসমান-পয়েন্ট গণিতের যথার্থতা, পাশাপাশি ভাসমান-পয়েন্ট ইউনিট ছাড়াই অনেকগুলি মেশিনে। দ্রষ্টব্য, বিটিডব্লিউ, যে বি, সি, এবং ডি এর মানগুলির উপর নির্ভর করে উপরোক্ত যেমন মত প্রকাশের জন্য উচ্চতর নির্ভুল মধ্যবর্তী গণনা ব্যবহার করেfloat a=b+c+d;কখনও কখনও ফলাফলগুলি পাওয়া যায় যা সমস্ত মধ্যবর্তী অপারেশনগুলির থেকে অর্জনের তুলনায় উল্লেখযোগ্যভাবে আরও নির্ভুল হয় যা নির্ভুলভাবে গণনা করা হত float, তবে কখনও কখনও এমন কোনও মান দেয় যা একটি সামান্য বিট কম নির্ভুল। যাইহোক, সান সিদ্ধান্ত নিয়েছে যে সমস্ত কিছু একইভাবে করা উচিত এবং তারা ন্যূনতম-নির্ভুলতার floatমানগুলি ব্যবহার করার পক্ষে বেছে নিয়েছিল ।

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


2

আসলে, একটি ছোট সুবিধা হবে। যদি তোমার কাছে থাকে একটা

class MyTimeAndDayOfWeek {
    byte dayOfWeek;
    byte hour;
    byte minute;
    byte second;
}

তারপরে একটি সাধারণ জেভিএম এর জন্য এটিতে একটি একক সমেত শ্রেণীর যতটা স্থান প্রয়োজন int। মেমরির খরচ পরের 8 বা 16 বাইট (আইআইআরসি, এটি কনফিগারযোগ্য) এর একাধিক সংখ্যায় গোল হয়ে যায়, তাই যখন সত্যিকারের সঞ্চয় থাকে তখন ক্ষেত্রেগুলি বিরল।

সম্পর্কিত ক্লাসটি যদি Calendarফিরে আসে তবে এই শ্রেণিটি ব্যবহার করা কিছুটা সহজ হবে byte। তবে এ জাতীয় কোনও Calendarপদ্ধতি নেই, কেবলমাত্র অন্যান্য ক্ষেত্রগুলির কারণে এটি get(int)অবশ্যই intপ্রদান করবে। ছোট ধরণের প্রতিটি অপারেশন প্রচার করে int, সুতরাং আপনার প্রচুর ingালাই প্রয়োজন need

সম্ভবত, আপনি হয় ছেড়ে দিন এবং একটি সেট intলিখুন বা পছন্দ মত সেটার

void setDayOfWeek(int dayOfWeek) {
    this.dayOfWeek = checkedCastToByte(dayOfWeek);
}

তারপরে DAY_OF_WEEKযাই হোক না কেন প্রকারের কিছু আসে যায় না।

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