c++ লগর প্রকারগুলি কেন সর্বদা একটি নির্দিষ্ট আকারের মূল্য বিবেচনা করে না?




সি ভাষার প্রোগ্রামের গঠন (16)

কারণ সি ++ এর মতো ভাষায়, একটি নকশার লক্ষ্য হ'ল সহজ অপারেশনগুলি সাধারণ মেশিনের নির্দেশাবলীতে সংকলিত হয়।

সমস্ত মূলধারার সিপিইউ নির্দেশাবলী স্থির-প্রস্থের প্রকারের সাথে কাজ করে এবং আপনি যদি ভেরিয়েবল-প্রস্থের প্রকারগুলি করতে চান, সেগুলি পরিচালনা করার জন্য আপনাকে একাধিক মেশিনের নির্দেশাবলী করতে হবে।

অন্তর্নিহিত কম্পিউটার হার্ডওয়্যারটি সেভাবে কেন এটি কারণ: এটি কারণ এটি অনেক সহজ এবং অনেক ক্ষেত্রেই কার্যকর (তবে সমস্ত নয়)।

কম্পিউটারটিকে টেপের টুকরো হিসাবে কল্পনা করুন:

| xx | xx | xx | xx | xx | xx | xx | xx | xx | xx | xx | xx | xx | ...

আপনি যদি কম্পিউটারকে কেবল টেপ, xx প্রথম বাইটটি দেখতে বলে থাকেন তবে টাইপটি সেখানে থামবে কি না বা কীভাবে তা পরের বাইটে এগিয়ে যায় তা কীভাবে জানতে পারে? আপনার যদি 255 (হেক্সাডেসিমাল FF ) এর মতো নম্বর থাকে বা 65535 (হেক্সাডেসিমাল FFFF ) এর মতো একটি নম্বর থাকে তবে প্রথম বাইটটি সর্বদা FF

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

সি এবং সি ++ এর মতো স্থির-প্রস্থের ভাষার ধরনগুলি এটি প্রতিফলিত করে।

এটি এ জাতীয় হতে হবে না, এবং আরও বিমূর্ত ভাষাগুলি যেগুলি সর্বাধিক দক্ষ কোডের সাথে ম্যাপিংয়ের সাথে কম জড়িত সেগুলি সংখ্যার প্রকারের জন্য ভেরিয়েবল-প্রস্থের এনকোডিংগুলি ("ভেরিয়েবল দৈর্ঘ্যের পরিমাণ" বা ভিএলকিউ হিসাবেও পরিচিত) ব্যবহার করতে পারে।

আরও পড়ুন: আপনি যদি "ভেরিয়েবল দৈর্ঘ্যের পরিমাণ" অনুসন্ধান করেন তবে এমন কিছু এনকোডিং আসলে দক্ষ এবং অতিরিক্ত যুক্তির পক্ষে মূল্যবান এমন কয়েকটি উদাহরণ আপনি খুঁজে পেতে পারেন। এটি সাধারণত যখন আপনাকে প্রচুর পরিমাণে মানগুলি সঞ্চয় করতে হয় যা বৃহত্তর পরিসরের মধ্যে যে কোনও জায়গায় হতে পারে তবে বেশিরভাগ মান কিছু ছোট উপ-সীমার দিকে ঝুঁকছে।

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

তবে , যখন কোডটি অন্য কোডগুলির সাথে পৃথকভাবে সংকলিত হতে পারে তার সাথে ইন্টার-অপারেটিং করতে হবে তখন মাপগুলিকে সামঞ্জস্য থাকতে হবে, বা কোডের প্রতিটি টুকরা একই কনভেনশন অনুসরণ করেছে তা নিশ্চিত করতে হবে।

কারণ এটি যদি ধারাবাহিক না হয় তবে এই জটিলতা রয়েছে: আমার কাছে যদি int x = 255; তবে তারপরে কোডে আমি x = y ? যদি int চলক-প্রস্থ হতে পারে, সর্বাধিক পরিমাণ জায়গার প্রয়োজন হবে এর পূর্বে বরাদ্দ করার জন্য সংকলকটি আগে সময় জানতে হবে। এটি সর্বদা সম্ভব নয়, কারণ y যদি অন্য একটি কোডের আলাদা আলাদাভাবে সংকলিত একটি আর্গুমেন্ট হয়?

বাস্তবের আকারের প্রকৃত আকারের মধ্যে পৃথক হতে পারে তবে বেশিরভাগ ক্ষেত্রে স্বাক্ষরযুক্ত ইনট এবং ফ্লোটের মতো প্রকারগুলি সর্বদা 4 বাইট। তবে কেন একটি প্রকার সর্বদা একটি নির্দিষ্ট পরিমাণ মেমরির দখল করে না তার মূল্য বিবেচনা করে? উদাহরণস্বরূপ, যদি আমি 255 এর মান দিয়ে নিম্নলিখিত পূর্ণসংখ্যা তৈরি করি

int myInt = 255;

তারপরে আমার myInt আমার বাইট 4 বাইট দখল করবে। তবে, আসল মান, 255 কেবলমাত্র 1 বাইট দ্বারা প্রতিনিধিত্ব করা যেতে পারে, তবে কেন আমার myInt কেবল 1 বাইট মেমরি দখল করবে না? বা জিজ্ঞাসার আরও সাধারণ পদ্ধতি: মানটির প্রতিনিধিত্ব করার জন্য প্রয়োজনীয় স্থানটি যদি সেই আকারের চেয়ে ছোট হতে পারে তবে কেন কোনও প্রকারের সাথে তার কেবলমাত্র একটি আকার যুক্ত হয়?


একটি ভেরিয়েবলের আকার পরিবর্তন করতে পুনঃনির্ধারণের প্রয়োজন হবে এবং মেমরির আরও কয়েকটি বাইট নষ্ট করার তুলনায় এটি অতিরিক্ত সিপিইউ চক্রের পক্ষে সাধারণত মূল্য নয়।

স্থানীয় ভেরিয়েবলগুলি একটি স্ট্যাকে চলে যায় যা যখন সেই ভেরিয়েবলগুলির আকারে পরিবর্তন হয় না তখন তা দ্রুত চালিত হয় to যদি আপনি স্থির করে থাকেন যে আপনি কোনও ভেরিয়েবলের আকার 1 বাইট থেকে 2 বাইটে প্রসারিত করতে চান তবে তার জন্য সেই স্থানটি তৈরি করতে আপনাকে স্ট্যাকের সমস্ত কিছু এক বাইটে স্থানান্তর করতে হবে। কতগুলি জিনিস সরিয়ে নেওয়া প্রয়োজন তার উপর নির্ভর করে এটিতে অনেকগুলি সিপিইউ চক্রের ব্যয় হতে পারে।

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

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


সংক্ষিপ্ত উত্তরটি হল: কারণ সি ++ স্ট্যান্ডার্ড তাই বলে।

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

আরেকটি বিষয় বিবেচনা করার বিষয় হ'ল কম্পিউটার মেমরি কীভাবে কাজ করে। ধরা যাক যে আপনার পূর্ণসংখ্যা টাইপটি স্টোরের 1 থেকে 4 বাইটের মধ্যে যে কোনও জায়গায় নিতে পারে। ধরুন আপনি 42 এর মানটি আপনার পূর্ণসংখ্যার মধ্যে সংরক্ষণ করেছেন: এটি 1 বাইট নেয় এবং আপনি এটি মেমরি ঠিকানার এক্সে রেখে দেন Then তারপরে আপনি আপনার পরবর্তী ভেরিয়েবলটি X + 1 অবস্থানে সংরক্ষণ করবেন (আমি এই মুহুর্তে প্রান্তিককরণ বিবেচনা করছি না) ইত্যাদি on । পরে আপনি নিজের মানটি 6424 এ পরিবর্তন করবেন।

তবে এটি একক বাইটের সাথে খাপ খায় না! তো তুমি কি কর? বাকিটা কোথায় রাখো? আপনার কাছে ইতিমধ্যে এক্স + 1 এ কিছু রয়েছে, তাই এটি সেখানে রাখতে পারবেন না। অন্য কোথাও? পরে কোথায় জানবেন কোথায়? কম্পিউটার মেমরিটি শব্দার্থবিজ্ঞান sertোকানো সমর্থন করে না: আপনি কেবল কোনও স্থানে কিছু রাখতে পারবেন না এবং জায়গা তৈরির জন্য সবকিছুকে পাশে রেখে চাপ দিতে পারবেন না!

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


জাভা ঠিক এটি করার জন্য "বিগইন্টেজার" এবং "বিগডিসিমাল" নামে ক্লাস ব্যবহার করে, যেমন সি ++ এর জিএমপি সি ++ ক্লাস ইন্টারফেস দৃশ্যত (ধন্যবাদ ডিজিটাল ট্রমা)। আপনি চাইলে আপনি সহজেই কোনও ভাষায় এটি নিজেই করতে পারেন।

সিপিইউতে সর্বদা BCD (বাইনারি কোডেড ডেসিমাল) ব্যবহারের দক্ষতা রয়েছে যা কোনও দৈর্ঘ্যের ক্রিয়াকলাপ সমর্থন করার জন্য ডিজাইন করা হয়েছে (তবে আপনি এক সময় নিজেই একটি বাইটে পরিচালনা করতে পারেন যা আজকের জিপিইউ স্ট্যান্ডার্ডের চেয়ে কম হবে) be

যে কারণে আমরা এই বা অন্যান্য অনুরূপ সমাধান ব্যবহার করি না? কর্মক্ষমতা. আপনার অত্যন্ত সর্বাধিক পারফরম্যান্ট ভাষাগুলি কিছু শক্ত লুপ ক্রিয়াকলাপের মাঝামাঝি কোনও ভেরিয়েবলের প্রসার ঘটাতে পারে না - এটি খুব অ-সং-বিরোধী হবে।

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

এটি একবার আপনার কম্পিউটারে ব্যবহার করা যেতে পারে যেখানে এটি ব্যবহার করা যেতে পারে, মেমরিটি সস্তা তবে পুনরায় আকার পরিবর্তনযোগ্য ভেরিয়েবলগুলির গতি এবং জটিলতা নয় .. এটিই কেবল কারণ।


সংকলকটি কিছু মেশিনের জন্য এসেমব্লার (এবং শেষ পর্যন্ত মেশিন কোড) তৈরি করার কথা বলে এবং সাধারণত সি ++ সেই মেশিনের প্রতি সহানুভূতিশীল হওয়ার চেষ্টা করে।

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

কংক্রিটলি, একটি নির্দিষ্ট মেশিন আর্কিটেকচার বিবেচনা করুন। চলুন বর্তমান ইন্টেল x86 পরিবারটি নেওয়া যাক।

ইন্টেল ®৪ এবং আইএ -32 আর্কিটেকচার সফটওয়্যার বিকাশকারীর ম্যানুয়াল ভল 1 ( link ), বিভাগ 3.4.1 এ বলেছে:

নিম্নলিখিত 32 টি বিট সাধারণ উদ্দেশ্য নিবন্ধগুলি EAX, EBX, ECX, EDX, ESI, EDI, EBP, এবং ESP সরবরাহ করে:

Log যৌক্তিক এবং গাণিতিক ক্রিয়াকলাপগুলির জন্য অপারেন্ডস

Address ঠিকানা গণনার জন্য অপারেন্ডস

• স্মৃতি পয়েন্টার

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

নিবন্ধগুলি সর্বদা একই আকারের (এখানে, 32 বিট) থাকে, সুতরাং আমার int ভেরিয়েবলগুলি সর্বদা 32 বিটও হবে। আমি একই লেআউটটি ব্যবহার করব (লিটল-এন্ডিয়ান) যাতে প্রতিবারই আমি কোনও রেজিস্টারে ভেরিয়েবলের মান লোড করতে না পারি, বা কোনও ভেরিয়েবলের মধ্যে কোনও রেজিস্টার সংরক্ষণ করতে পারি।

godbolt ব্যবহার করে আমরা দেখতে পাচ্ছি যে সংকলক কিছু তুচ্ছ কোডের জন্য ঠিক কী করে:

int square(int num) {
    return num * num;
}

সংকলন (সরলতার জন্য জিসিসি 8.1 এবং -fomit-frame-pointer -O3 ) এতে:

square(int):
  imul edi, edi
  mov eax, edi
  ret

এর অর্থ:

  1. int num প্যারামিটারটি int num রেজিস্টারে পাস করা হয়েছিল, এর অর্থ এটি হ'ল আকার এবং বিন্যাস ইন্টেল কোনও স্থানীয় নিবন্ধকের জন্য প্রত্যাশা করে। ফাংশনটি কিছুই রূপান্তর করতে হবে না
  2. গুণটি একটি একক নির্দেশ ( imul ), যা খুব দ্রুত
  3. ফলাফলটি ফিরিয়ে দেওয়া কেবল এটি অন্য রেজিস্টারে অনুলিপি করার বিষয় (কলার আশা করেন যে ফলাফলটি EAX এ দেওয়া হবে)

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

godbolt আবার ব্যবহার করে আমরা একটি সাধারণ দেশীয় godbolt তুলনা করতে পারি

unsigned mult (unsigned x, unsigned y)
{
    return x*y;
}

mult(unsigned int, unsigned int):
  mov eax, edi
  imul eax, esi
  ret

একটি অ-মানক প্রস্থের সমতুল্য কোড সহ

struct pair {
    unsigned x : 31;
    unsigned y : 31;
};

unsigned mult (pair p)
{
    return p.x*p.y;
}

mult(pair):
  mov eax, edi
  shr rdi, 32
  and eax, 2147483647
  and edi, 2147483647
  imul eax, edi
  ret

সমস্ত অতিরিক্ত নির্দেশাবলী ইনপুট ফর্ম্যাটটি (দুটি 31-বিট স্বাক্ষরযুক্ত স্বাক্ষর) প্রসেসর স্থানীয়ভাবে পরিচালনা করতে পারে এমন ফর্ম্যাটে রূপান্তর করার সাথে সম্পর্কিত। যদি আমরা ফলাফলটি 31-বিট মানতে আবার সঞ্চয় করতে চাই, তবে এটি করার জন্য আরও একটি বা দুটি নির্দেশ থাকবে।

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

গতিশীল আকারের একটি নোট:

উপরের উদাহরণটি এখনও ভেরিয়েবল-প্রস্থের পরিবর্তে স্থির-প্রস্থের মান, তবে প্রস্থ (এবং প্রান্তিককরণ) আর দেশীয় নিবন্ধগুলির সাথে মেলে না।

এক্স 86। প্ল্যাটফর্মটির কয়েকটি স্থানীয় আকার রয়েছে যার মধ্যে প্রধান 32-বিট ছাড়াও 8-বিট এবং 16-বিট রয়েছে (আমি 64 64-বিট মোডে এবং অন্যান্য সরলতার জন্য বিভিন্ন কিছুর উপরে গ্লোস করছি)।

এই ধরণের (চর, int8_t, uint8_t, int16_t ইত্যাদি) আর্কিটেকচার দ্বারা সরাসরি সমর্থিত - আংশিকভাবে পুরানো 8086/286/386 / ইত্যাদির সাথে পিছনের দিকের সামঞ্জস্যের জন্য। ইত্যাদি নির্দেশাবলী সেট।

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

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

দক্ষতার উপর একটি আরও নোট

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

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

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

TL; ড

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


এটি একটি অপ্টিমাইজেশন এবং সরলকরণ।

আপনি হয় স্থির আকারের বস্তু থাকতে পারে। এইভাবে মান সংরক্ষণ করা।
অথবা আপনার পরিবর্তনশীল আকারের আপত্তি থাকতে পারে। তবে মান এবং আকার সংরক্ষণ করছে।

স্থির আকারের বস্তু

কোডটি যে সংখ্যাটি ম্যানিপুলেট করে সেগুলির আকার সম্পর্কে চিন্তা করার দরকার নেই। আপনি ধরে নেন যে আপনি সর্বদা 4 বাইট ব্যবহার করেন এবং কোডটি খুব সহজ করে তোলে।

গতিশীল আকারের বস্তু

নম্বরটি যে কোডটি পরিচালনা করে তা ভেরিয়েবলটি পড়ার সময় অবশ্যই বুঝতে হবে যে এটির মান এবং আকারটি অবশ্যই পড়তে হবে। নিবন্ধে সমস্ত উচ্চ বিট শূন্য রয়েছে কিনা তা নিশ্চিত করতে আকারটি ব্যবহার করুন।

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

সারাংশ

স্থির আকারের বস্তুর জন্য উত্পন্ন কোডটি অনেক সহজ।

বিঃদ্রঃ

সংক্ষেপণ 255 এক বাইট মধ্যে মাপসই করা হবে যে সত্য ব্যবহার করে। বৃহত ডেটা সেটগুলি সংরক্ষণ করার জন্য সংক্ষেপণ স্কিম রয়েছে যা বিভিন্ন সংখ্যার জন্য সক্রিয়ভাবে বিভিন্ন আকারের মান ব্যবহার করবে। তবে এটি লাইভ ডেটা না হওয়ায় আপনার উপরে বর্ণিত জটিলতা নেই। আপনি সঞ্চয় করার জন্য ডেটা কমপ্রেসিং / ডি-কমপ্রেসিংয়ে ব্যয় করে ডেটা সঞ্চয় করতে কম স্থান ব্যবহার করেন।


এখানে কিছু কারন আছে। এক হ'ল স্বেচ্ছাসেবক আকারের সংখ্যাগুলি পরিচালনা করার জন্য এটি একটি যুক্ত জটিলতা এবং এতে পারফরম্যান্সটি হিট হয় কারণ সংকলক আর এই অনুমানের উপর ভিত্তি করে অনুকূলকরণ করতে পারে না যে প্রতিটি ইনট ঠিক এক্স বাইট দীর্ঘ।

দ্বিতীয়টি হ'ল সহজ প্রকারগুলিকে এভাবে সংরক্ষণ করা মানে দৈর্ঘ্য ধরে রাখতে তাদের অতিরিক্ত বাইটের প্রয়োজন। সুতরাং, 255 বা তারও কম মূল্যের এই নতুন সিস্টেমে দুটি বাইট প্রয়োজন, একটি নয় এবং সবচেয়ে খারাপ ক্ষেত্রে আপনার এখন 4 এর পরিবর্তে 5 বাইট প্রয়োজন need এর অর্থ হল যে ব্যবহৃত মেমরির ক্ষেত্রে পারফরম্যান্স জয়ের কথা আপনার তুলনায় কম is ভাবেন এবং কিছু প্রান্তে আসলে নেট ক্ষতি হতে পারে।

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

পাদটীকা: আরও সুনির্দিষ্ট হওয়ার জন্য, আপনি বাইটগুলিতে সম্বোধন করার সময়, বেশিরভাগ সিস্টেমগুলি 'অসম' বাইটগুলি উপেক্ষা করে। অর্থাৎ, ঠিকানা 0, 1, 2 এবং 3 সমস্ত একই শব্দটি পড়েন, 4, 5, 6 এবং 7 পরবর্তী শব্দটি পড়ুন, ইত্যাদি।

রিলিজবিহীন নোটে, এ কারণেই 32-বিট সিস্টেমে সর্বোচ্চ 4 জিবি মেমরি ছিল। মেমোরিতে অবস্থানগুলির ঠিকানাগুলির জন্য ব্যবহৃত নিবন্ধগুলি সাধারণত কোনও শব্দ ধরে রাখার পক্ষে যথেষ্ট বড় হয়, অর্থাৎ 4 বাইট, যার সর্বাধিক মান হয় (2 ^ 32) -1 = 4294967295 42 4294967296 বাইট 4 জিবি।


কারণ ডায়নামিক আকারের সাথে সাধারণ ধরণগুলি রাখা খুব জটিল এবং গণনা ভারী হবে। আমি নিশ্চিত না যে এটি এমনকি সম্ভব হবে।
কম্পিউটারের প্রতিটি মান পরিবর্তনের পরে কত বিট লাগে তা পরীক্ষা করে দেখতে হবে to এটি বেশ অনেকগুলি অতিরিক্ত অপারেশন হবে। যখন আপনি সংকলনের সময় আকারের ভেরিয়েবলগুলি জানেন না তখন হিসাব করা খুব বেশি শক্ত হবে be

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

কম্পিউটার কীভাবে কাজ করে এবং ভেরিয়েবলের কেন ধ্রুব আকার থাকে তা আরও ভালভাবে বুঝতে, এসেম্বলারের ভাষার বুনিয়াদি শিখুন।

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

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

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


কম্পিউটার মেমরিটি একটি নির্দিষ্ট আকারের ক্রমাগত-সম্বোধিত অংশগুলিতে বিভক্ত হয় (প্রায়শই 8 টি বিট, এবং বাইট হিসাবে পরিচিত), এবং বেশিরভাগ কম্পিউটারগুলি পর পর ঠিকানাগুলি বাইটের ক্রমগুলি দক্ষতার সাথে অ্যাক্সেস করার জন্য তৈরি করা হয়।

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


এমন কিছু সহজ যা বেশিরভাগ উত্তরগুলি মিস করে বলে মনে হচ্ছে:

কারণ এটি সি ++ এর ডিজাইনের লক্ষ্য অনুসারে।

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

সম্ভবত মুখ্য কারণ সি ++ স্থির আকারের ধরণের প্রতি দৃ strongly়ভাবে ঝুঁকিতে ফেলেছে এটি সি এর সামঞ্জস্যের লক্ষ্য। তবে, যেহেতু সি ++ একটি স্ট্যাটিকালি-টাইপযুক্ত ভাষা যা খুব দক্ষ কোড তৈরি করার চেষ্টা করে এবং প্রোগ্রামার দ্বারা স্পষ্টভাবে নির্দিষ্ট না করে এমন জিনিস যুক্ত করা এড়িয়ে যায়, তাই স্থির আকারের ধরণগুলি এখনও অনেক কিছু বোঝায়।

তাহলে সি স্থির আকারের ধরণগুলি প্রথম স্থানে কেন বেছে নিয়েছিল? সহজ। এটি '70s-যুগের অপারেটিং সিস্টেম, সার্ভার সফ্টওয়্যার এবং ইউটিলিটিগুলি লেখার জন্য ডিজাইন করা হয়েছিল; অন্যান্য সফ্টওয়্যারগুলির জন্য অবকাঠামো (যেমন মেমরি পরিচালনা) সরবরাহ করে। এত নিম্ন স্তরে, কর্মক্ষমতা সমালোচনামূলক এবং তাই সংকলকটি আপনি যা বলছেন তা অবিকলভাবে করছে।


কম্পাইলারটি আপনার কোডগুলিতে অনেকগুলি পরিবর্তন করার অনুমতি দেয়, যতক্ষণ না জিনিসগুলি এখনও কাজ করে ("যেমন রয়েছে" বিধি)।

একটি পূর্ণ স্থানান্তরিত করার জন্য প্রয়োজনীয় আরও দীর্ঘ (32/64 বিট) এর পরিবর্তে 8-বিট আক্ষরিক চলন নির্দেশাবলী ব্যবহার করা সম্ভব হবে int । তবে লোডটি সম্পন্ন করার জন্য আপনার দুটি নির্দেশের প্রয়োজন হবে, কারণ লোডটি করার আগে আপনাকে প্রথমে শূন্যে রেজিস্টারটি সেট করতে হবে।

32 বিট হিসাবে মানটি পরিচালনা করতে এটি কেবল আরও দক্ষ (কমপক্ষে মূল সংকলক অনুসারে) is প্রকৃতপক্ষে, আমি এখনও একটি x86 / x86_64 সংকলক দেখতে পেল যা ইনলাইনে সমাবেশ না করে 8-বিট লোড করতে পারে।

যাইহোক, জিনিসগুলি 64৪ বিটের ক্ষেত্রে আলাদা different তাদের প্রসেসরের পূর্ববর্তী এক্সটেনশনগুলি (16 থেকে 32 বিট পর্যন্ত) ডিজাইন করার সময়, ইন্টেল একটি ভুল করেছিল। তারা দেখতে কেমন তার একটি ভাল উপস্থাপনা Here । এখানে মূল অবলম্বন হ'ল আপনি যখন AL বা এএইচ-তে লিখেন তখন অন্যটি প্রভাবিত হয় না (যথেষ্ট ন্যায্যতা, এটিই ছিল এবং এটি তখন ফিরে এসেছিল)। তারা আকর্ষণীয় হয়ে ওঠে যখন তারা এটিকে 32 বিটে প্রসারিত করে। আপনি নীচে বিট (আওয়ামী লীগ হিঃ বা কুঠার) লেখেন, তাহলে কিছুই EAX, যার মানে আপনি একটি প্রচার করতে চায় উপরের 16 বিট ঘটবে char একটি মধ্যে int , আপনাকে প্রথমে মেমরি পরিষ্কার প্রয়োজন, কিন্তু আপনার কোন উপায় আছে প্রকৃতপক্ষে কেবলমাত্র এই শীর্ষ 16 টি বিট ব্যবহার করে, এই "বৈশিষ্ট্য "টিকে কোনও কিছুর চেয়ে বেশি ব্যথা করে।

এখন 64 বিট সহ, এএমডি আরও ভাল কাজ করেছে। আপনি যদি নিম্ন 32 বিটগুলিতে কোনও কিছু স্পর্শ করেন তবে উপরের 32 বিটগুলি কেবল 0 তে সেট করা থাকে some এটি কিছু প্রকৃত অপ্টিমাইজেশনের দিকে পরিচালিত করে যা আপনি এই godbolt দেখতে godbolt । আপনি দেখতে পাচ্ছেন যে 8 টি বিট বা 32 বিটের কিছু লোড করা একইভাবে করা হয়, তবে আপনি যখন 64 বিট ভেরিয়েবল ব্যবহার করেন, তখন সংকলকটি আপনার আক্ষরিকের প্রকৃত আকারের উপর নির্ভর করে একটি ভিন্ন নির্দেশনা ব্যবহার করে।

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


সুতরাং কেন আমার আইটেমটি কেবল 1 বাইট মেমরি দখল করবে না?

কারণ আপনি এটিকে অনেক বেশি ব্যবহার করতে বলেছিলেন। একটি ব্যবহার করার সময় unsigned int , কিছু মান নির্দেশ করে যে 4 বাইট ব্যবহার করা হবে এবং এটির জন্য উপলব্ধ পরিসীমা 0 থেকে 4,294,967,295 হবে। আপনি যদি এর unsigned char পরিবর্তে ব্যবহার করতে চান তবে আপনি সম্ভবত যে 1 বাইটটি সন্ধান করছেন কেবল এটিই ব্যবহার করতেন (স্ট্যান্ডার্ড এবং সি ++ এর উপর নির্ভর করে সাধারণত এই স্ট্যান্ডার্ডগুলি ব্যবহার করে)।

যদি এই মানগুলি না হয় তবে আপনাকে এটিকে মনে রাখতে হবে: সংকলক বা সিপিইউ কীভাবে 4 এর পরিবর্তে কেবলমাত্র 1 বাইট ব্যবহার করতে জানে? পরে আপনার প্রোগ্রামে আপনি সেই মানটি যোগ বা গুণিত করতে পারেন, যার জন্য আরও স্থানের প্রয়োজন হবে। আপনি যখনই কোনও মেমরি বরাদ্দ করেন, তখন ওএসকে আপনাকে সেই স্থানটি খুঁজে পেতে, মানচিত্র করতে হয় এবং আপনাকে সেই স্থানটি দিতে হয় (ভার্চুয়াল র‍্যামেও সম্ভাব্যরূপে মেমরি অদলবদল করতে হয়); এটি একটি দীর্ঘ সময় নিতে পারে। আপনি যদি হাতের আগে মেমরি বরাদ্দ করেন তবে আপনাকে আর বরাদ্দ শেষ হওয়ার জন্য অপেক্ষা করতে হবে না।

যে কারণে আমরা বাইট প্রতি 8 টি বিট ব্যবহার করি, আপনি এটি একবার খেয়াল করতে পারেন: বাইট আট বিট হওয়ার ইতিহাস কী?

পার্শ্ব নোটে, আপনি পূর্ণসংখ্যাকে উপচে পড়তে দিতে পারবেন; তবে আপনি যদি স্বাক্ষরিত পূর্ণসংখ্যা ব্যবহার করেন তবে সি \ সি ++ স্ট্যান্ডার্ডগুলি উল্লেখ করে যে পূর্ণসংখ্যার ওভারফ্লোগুলি অনির্ধারিত আচরণের ফলে ঘটে। পূর্ণসংখ্যা ওভারফ্লো


তারপরে আমার myInt আমার বাইট 4 বাইট দখল করবে। তবে, আসল মান, 255 কেবলমাত্র 1 বাইট দ্বারা প্রতিনিধিত্ব করা যেতে পারে, তবে কেন আমার myInt কেবল 1 বাইট মেমরি দখল করবে না?

এটি ভেরিয়েবল-লেংথ এনকোডিং হিসাবে পরিচিত, বিভিন্ন এনকোডিংগুলি সংজ্ঞায়িত করা হয়েছে, উদাহরণস্বরূপ VLQ । তবে সর্বাধিক বিখ্যাতগুলির মধ্যে একটি হ'ল ইউটিএফ -8 : ইউটিএফ -8 এনকোড কোড পয়েন্টগুলি 1 থেকে 4 এর চলক সংখ্যক বাইটে সংযুক্ত করে points

বা জিজ্ঞাসার আরও সাধারণ পদ্ধতি: মানটির প্রতিনিধিত্ব করার জন্য প্রয়োজনীয় স্থানটি যদি সেই আকারের চেয়ে ছোট হতে পারে তবে কেন কোনও প্রকারের সাথে তার কেবলমাত্র একটি আকার যুক্ত হয়?

ইঞ্জিনিয়ারিংয়ের মতো সর্বদা ট্রেড-অফ সম্পর্কে about এমন কোনও সমাধান নেই যার কেবল সুবিধা রয়েছে, সুতরাং আপনার সমাধানটি ডিজাইন করার সময় আপনাকে সুবিধাগুলি এবং ট্রেড-অফগুলিতে ভারসাম্য বজায় রাখতে হবে।

যে নকশাটি স্থির করা হয়েছিল তা হ'ল স্থির আকারের মৌলিক ধরণের ব্যবহার করা এবং হার্ডওয়্যার / ভাষাগুলি সেখান থেকে নেমে এসেছিল।

সুতরাং, পরিবর্তনশীল এনকোডিংয়ের মৌলিক দুর্বলতা কী, যা এটি আরও মেমরি ক্ষুধার্ত প্রকল্পগুলির পক্ষে প্রত্যাখ্যান করে? কোন এলোমেলো ঠিকানা

ইউটিএফ -8 স্ট্রিংয়ে ৪ র্থ কোড পয়েন্ট শুরু হওয়া বাইটের সূচকটি কী?

এটি পূর্ববর্তী কোড পয়েন্টগুলির মানগুলির উপর নির্ভর করে, একটি লিনিয়ার স্ক্যান প্রয়োজন।

অবশ্যই এখানে ভেরিয়েবল-দৈর্ঘ্যের এনকোডিং স্কিমগুলি রয়েছে যা এলোমেলো-ঠিকানাতে আরও ভাল?

হ্যাঁ, তবে এগুলি আরও জটিল। যদি কোনও আদর্শ থাকে তবে আমি এটি এখনও কখনও দেখিনি।

এলোমেলোভাবে সম্বোধন আসলেই কি গুরুত্বপূর্ণ?

হ্যাঁ!

জিনিসটি হ'ল যে কোনও ধরণের সমষ্টি / অ্যারে স্থির আকারের ধরণের উপর নির্ভর করে:

  • একটি কাঠামোর তৃতীয় ক্ষেত্র অ্যাক্সেস? এলোমেলো সম্বোধন!
  • একটি অ্যারের তৃতীয় উপাদান অ্যাক্সেস করছেন? এলোমেলো সম্বোধন!

যার অর্থ আপনার কাছে নিম্নলিখিত বাণিজ্য বন্ধ রয়েছে:

স্থির আকারের আকার বা লিনিয়ার মেমরি স্ক্যান


মান উপস্থাপনের জন্য প্রয়োজনীয় স্থানটি সেই আকারের চেয়ে ছোট হতে পারে কেন কোনও প্রকারের সাথে তার কেবলমাত্র একটি আকার যুক্ত থাকে?

মূলত সারিবদ্ধকরণ প্রয়োজনীয়তার কারণে।

অনুযায়ী basic.align/1 :

অবজেক্টের ধরণের প্রান্তিককরণের প্রয়োজনীয়তা রয়েছে যা ঠিকানার উপরে বিধিনিষেধ রাখে যেখানে এই ধরণের একটি অবজেক্ট বরাদ্দ করা যেতে পারে।

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

যদি ঘরগুলি সারিবদ্ধ না হয়, তবে বিল্ডিং কঙ্কালটি সুসংগঠিত হবে না।


আমি সের্গির ঘরের সাদৃশ্য পছন্দ করি তবে আমি মনে করি একটি গাড়ী উপমা আরও ভাল হবে।

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

আপনার যদি একটি লিমুজিন থাকে এবং আপনি একা ড্রাইভিং করেন তবে এটি কেবল আপনার ফিটনেই সঙ্কুচিত হবে না। এটি করার জন্য, আপনাকে গাড়িটি বিক্রি করতে হবে (পড়ুন: ডিলোকেট) এবং নিজের জন্য একটি নতুন ছোট একটি কিনতে হবে।

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

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


এটি কম হতে পারে। ফাংশনটি বিবেচনা করুন:

int foo()
{
    int bar = 1;
    int baz = 42;
    return bar+baz;
}

এটি অ্যাসেম্বলি কোডে সংকলিত হয় (g ++, x64, বিশদ বিবরণ)

$43, %eax
ret

এখানে, bar এবং baz উপস্থাপনের জন্য শূন্য বাইট ব্যবহার করে শেষ করুন।





c++