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


149

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

int myInt = 255;

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


15
1) " তবে, আসল মান 256 কেবলমাত্র 1 বাইটের সাথে উপস্থাপিত হতে পারে " রং, বৃহত্তম unsingedমান, যা 1 বাইটের সাথে প্রতিনিধিত্ব করা যায় 255। ২) মান পরিবর্তনের সাথে সাথে সর্বোত্তম সঞ্চয়স্থানের আকার গণনা করার এবং ভেরিয়েবলের সঞ্চয় স্থানটি সঙ্কুচিত / প্রসারিত করার বিষয়টি বিবেচনা করুন।
আলগিরদাস প্রিডিয়াস

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

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

37
ভেরিয়েবলের মানটিতে 1 যোগ করে 256 তৈরি করে কী ঘটবে তা বিবেচনা করুন, সুতরাং এর প্রসারিত হওয়া দরকার। এটি কোথায় প্রসারিত হয়? আপনি কি বাকী স্মৃতি স্থান স্থান পরিবর্তন করতে চান? ভেরিয়েবল নিজেই নড়ে? যদি এটি হয়ে থাকে তবে এটি কোথায় স্থানান্তরিত হবে এবং আপনাকে আপডেট করতে হবে এমন পয়েন্টারগুলি কীভাবে খুঁজে পাবেন?
molbdnilo

13
@ সোমিডিয়ট নাহ, আপনি ভুল std::vector<X>সর্বদা একই আকার থাকে, অর্থাত sizeof(std::vector<X>)একটি সংকলন-সময় ধ্রুবক।
সের্গেইএ

উত্তর:


131

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

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

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

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

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

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

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

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

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

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

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

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

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

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

এর অর্থ:

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

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

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

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 / ইত্যাদি পিছন সামঞ্জস্যের জন্য। ইত্যাদি নির্দেশাবলী সেট।

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

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


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

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

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

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


TL; ড

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


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

7
@ এএসডি তবে আপনি কোডটিতে কয়টি রেজিস্টার ব্যবহার করবেন যা বর্তমানে একটি রেজিস্টারে কতগুলি ভেরিয়েবল সঞ্চিত আছে তা নির্ধারণ করে?
ব্যবহারকারী 253751

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

3
আমি আসলে এমন না কিছু মান জন্য সব 32 বিটের প্রয়োজন, আমার এখনও কোথাও দৈর্ঘ্য সঞ্চয় করতে তাই এখন আমি প্রয়োজন হবে, চেয়ে বেশি কিছু ক্ষেত্রে 32 বিট।
অকেজো

1
+1 টি। সম্পর্কে "সরল ও প্রাকৃতিক বিন্যাস এবং তারপর কম্প্রেস" সাধারণত ভাল হচ্ছে একটি নোট: এই হ 'ল হয় সাধারনতঃ সত্য , কিন্তু : কিছু তথ্য VLQ-প্রতিটি মান-তারপর-কম্প্রেস-পুরো জিনিস সঞ্চালিত উল্লেখযোগ্য হল শুধু চেয়ে ভাল জন্য কম্প্রেস- -হোলো-জিনিস, এবং কিছু অ্যাপ্লিকেশনগুলির জন্য, আপনার ডেটা একসাথে সংকুচিত করা যায় না , কারণ এটি হয় পৃথক (যেমন gitমেটাডাটা হিসাবে) বা আপনি আসলে এটিকে স্মৃতিতে রাখছেন মাঝে মাঝে এলোমেলোভাবে অ্যাক্সেস বা সংশোধন করতে হবে তবে বেশিরভাগেরই নয় মানগুলি (এইচটিএমএল + সিএসএস রেন্ডারিং ইঞ্জিনগুলির মতো), এবং কেবলমাত্র জায়গায় জায়গায় ভিএলকিউয়ের মতো কিছু ব্যবহার করে এড়ানো যেতে পারে।
mtraceur

139

কারণ প্রকারভেদগুলি মূলত স্টোরেজকে উপস্থাপন করে এবং বর্তমান মানটি না করে তারা ধরে রাখতে পারে এমন সর্বোচ্চ মানের সাথে সংজ্ঞাযুক্ত।

খুব সাধারণ উপমা একটি বাড়ি হবে - একটি বাড়ির একটি নির্দিষ্ট আকার থাকে, যত লোক এতে বাস করুক না কেন, এবং এখানে একটি বিল্ডিং কোডও রয়েছে যা একটি নির্দিষ্ট আকারের ঘরে বসবাস করতে পারে এমন সর্বাধিক সংখ্যক লোককে নির্ধারিত করে।

যাইহোক, এমনকি যদি কোনও একক ব্যক্তি 10 বাড়িতে থাকতে পারে এমন ঘরে বাস করেন, তবে বাড়ির আকারটি বর্তমানে দখলদারদের দ্বারা প্রভাবিত হবে না।


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

5
"কারণ প্রকারভেদগুলি মূলত
স্টোরেজকে

56
@ Corvus_192 ট্যাগগুলির অর্থ রয়েছে। এই প্রশ্নটি সি ++ দিয়ে ট্যাগ করা হয়েছে, '
টাইপস্ক্রিপ্ট

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

2
@ জেমসেকফ সম্ভবত এমপি পাটিগণিত লিস্পে প্রথমে গ্রহণ করেছিলেন এটি স্বয়ংক্রিয় মেমরি পরিচালনাও সম্ভব নয়। ডিজাইনাররা মনে করেছিলেন যে পারফরম্যান্সের প্রভাবগুলি প্রোগ্রামিংয়ের স্বাচ্ছন্দ্যের চেয়ে গৌণ। এবং প্রভাবটি হ্রাস করতে অনুকূলকরণ কৌশলগুলি তৈরি করা হয়েছিল।
বর্মার

44

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

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

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

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

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

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

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

সারসংক্ষেপ

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

বিঃদ্রঃ

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


4
এটি আমার পক্ষে সেরা উত্তর: আপনি কীভাবে আকারটি রাখছেন? সঙ্গে আরও মেমরির?
অনলাইন টমাস

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

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

27

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

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

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

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

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

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

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

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

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

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


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

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

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


26

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

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

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

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

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


4
কেউ বিগইন্টেজারের উল্লেখ দেখে খুশি হলেন। এটি যে নিরীহ ধারণা নয়, এটি কেবলমাত্র অত্যন্ত সংখ্যক ব্যক্তির জন্য এটি করার জন্য বোধগম্য।
সর্বাধিক ব্যারাক্লফ

1
পেডেন্টিক হওয়ার জন্য আপনি আসলে খুব সুনির্দিষ্ট সংখ্যার অর্থ বোঝাচ্ছেন :) ঠিক আছে কমপক্ষে বিগডিসিমেলের ক্ষেত্রে ...
বিল কে

2
এবং যেহেতু এটি সি ++ ট্যাগ করা হয়েছে , এটি সম্ভবত জিএমপি সি ++ শ্রেণি ইন্টারফেসের উল্লেখযোগ্য , যা জাভা এর বিগ * হিসাবে একই ধারণা।
ডিজিটাল ট্রমা

20

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

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

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

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

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


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


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

1
আমি বরং স্বাভাবিক ভেরিয়েবল দ্বারা গুণিত কনস্টেক্সপ্র ভেরিয়েবলের মতো ক্রিয়াকলাপগুলি সম্পর্কে ভাবছিলাম। উদাহরণস্বরূপ আমাদের কাছে (তাত্ত্বিকভাবে) 8-বাইট কনসেক্সেক্সপ্র ভেরিয়েবল রয়েছে 56এবং আমরা এটি 2-বাইট ভেরিয়েবল দ্বারা গুণ করি। কিছু আর্কিটেকচারে bit৪-বিট অপারেশন আরও বেশি ভারী গণনা হবে তাই সংকলক কেবলমাত্র ১ 16-বিট গুণিত করতে এটি অনুকূল করতে পারে।
NO_NAME

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

16

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

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

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

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

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

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

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

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

অবশ্যই এখানে ভেরিয়েবল-লেংথ এনকোডিং স্কিমগুলি রয়েছে যা এলোমেলো সম্বোধনে ভাল?

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

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

হ্যাঁ!

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

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

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

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


এটি যতটা সমস্যার সমাধান করবে তেমন সমস্যা নয়। আপনি সবসময় ভেক্টর টেবিল ব্যবহার করতে পারেন। একটি মেমরি ওভারহেড এবং একটি অতিরিক্ত আনয়ন আছে তবে লিনিয়ার স্ক্যানগুলি প্রয়োজনীয় নয়।
আর্টিলিয়াস

2
@ আর্টেলিয়াস: পূর্ণসংখ্যার পরিবর্তনশীল প্রস্থ যখন আপনি ভেক্টর টেবিলটি কীভাবে এনকোড করবেন? এছাড়াও, মেমরিতে 1 থেকে 4 বাইট ব্যবহার করে এমন পূর্ণসংখ্যার জন্য একটি এনকোড করার সময় ভেক্টর টেবিলের মেমরি ওভারহেড কী?
ম্যাথিউ এম।

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

@ আর্টেলিয়াস: দ্রষ্টব্য যে পাইথনে অ্যারেতে উপাদানগুলিতে নির্দিষ্ট আকারের পয়েন্টার রয়েছে ; এটি কোনও দিকনির্দেশের ব্যয়ে কোনও উপাদানে যেতে ও (1) তৈরি করে।
ম্যাথিউ এম।

16

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

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


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

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

13

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

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

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

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

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


11

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

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


11

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

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

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

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

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


10

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

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

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

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

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


8

সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে এমন কিছু বস্তু রয়েছে যা কিছু দিক থেকে পরিবর্তনশীল আকার ধারণ করে std::vector। যাইহোক, এই সমস্ত গতিশীলভাবে তাদের অতিরিক্ত মেমরির প্রয়োজন হবে alloc আপনি যদি গ্রহণ করেন তবে আপনি sizeof(std::vector<int>)একটি ধ্রুবক পাবেন যা অবজেক্ট দ্বারা পরিচালিত মেমরির সাথে কোনও সম্পর্ক রাখে না এবং যদি আপনি কোনও অ্যারে বা কাঠামো সমন্বিত বরাদ্দ std::vector<int>করেন তবে এটি একই অ্যারে বা কাঠামোয় অতিরিক্ত সঞ্চয়স্থান রাখার পরিবর্তে এই বেস আকারটি সংরক্ষণ করবে । সি সিনট্যাক্সের কয়েকটি টুকরা রয়েছে যা এই জাতীয় কিছু সমর্থন করে, উল্লেখযোগ্যভাবে ভেরিয়েবল-দৈর্ঘ্যের অ্যারে এবং কাঠামো, তবে সি ++ তাদের সমর্থন করা পছন্দ করেনি।

ভাষার স্ট্যান্ডার্ড বস্তুর আকারটিকে সেভাবে সংজ্ঞায়িত করে যাতে সংকলকরা দক্ষ কোড তৈরি করতে পারে। উদাহরণস্বরূপ, যদি intকিছু প্রয়োগে 4 বাইট দীর্ঘ হয় এবং আপনি মানগুলির aপয়েন্টার বা অ্যারের হিসাবে ঘোষণা করেন int, তবে a[i]সিউডোকোডে অনুবাদ করুন, "ঠিকানাটি +4 × i অবলম্বন করুন” " এটি ধ্রুবক সময়ে করা যেতে পারে এবং এটি এমন একটি সাধারণ এবং গুরুত্বপূর্ণ ক্রিয়াকলাপ যা x86 এবং DEC PDP মেশিন সহ অনেকগুলি ইনস্ট্রাকচার-সেট আর্কিটেকচার, যার ভিত্তিতে সি তৈরি হয়েছিল, এটি একক মেশিনের নির্দেশে এটি করতে পারে।

ভেরিয়েবল-লেন্থ ইউনিট হিসাবে ক্রমাগতভাবে সংরক্ষণ করা তথ্যের এক সাধারণ বাস্তব-বিশ্বের উদাহরণ ইউটিএফ -8 হিসাবে এনকোড করা স্ট্রিং। (তবে, সংকলকটিতে একটি ইউটিএফ -8 স্ট্রিংয়ের অন্তর্নিহিত ধরণটি এখনও charপ্রস্থ এবং এর প্রস্থ 1 রয়েছে This এটি ASCII স্ট্রিংগুলিকে বৈধ ইউটিএফ -8 হিসাবে ব্যাখ্যা করতে পারে এবং প্রচুর লাইব্রেরি কোড যেমন strlen()এবং strncpy()কাজ চালিয়ে যেতে পারে)) যে কোনও ইউটিএফ -8 কোডপয়েন্টের এনকোডিং এক থেকে চার বাইট দীর্ঘ হতে পারে এবং তাই আপনি যদি একটি স্ট্রিংয়ে পঞ্চম ইউটিএফ -8 কোডপয়েন্ট চান তবে এটি পঞ্চম বাইট থেকে শুরু করে সতেরো বাইট পর্যন্ত শুরু হতে পারে। এটির সন্ধান করার একমাত্র উপায় হ'ল স্ট্রিংয়ের শুরু থেকে স্ক্যান করা এবং প্রতিটি কোডপয়েন্টের আকার পরীক্ষা করা। আপনি যদি পঞ্চম গ্রাফি পেতে চান, আপনার চরিত্রের ক্লাসগুলিও পরীক্ষা করা দরকার। আপনি যদি একটি স্ট্রিংয়ে মিলিয়নতম ইউটিএফ -8 অক্ষর সন্ধান করতে চান তবে আপনার এই লুপটি এক মিলিয়ন বার চালানো দরকার! আপনি যদি জানেন যে আপনাকে প্রায়শই সূচকের সাথে কাজ করতে হবে, আপনি একবার স্ট্রিংটি অতিক্রম করতে পারেন এবং এর সূচি তৈরি করতে পারেন। বা আপনি একটি নির্দিষ্ট-প্রস্থের এনকোডিংতে রূপান্তর করতে পারেন, যেমন ইউসিএস -4। স্ট্রিংয়ে মিলিয়নতম ইউসিএস -4 অক্ষর সন্ধান করা অ্যারের ঠিকানার সাথে চার মিলিয়ন যোগ করার বিষয় is

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

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

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


7

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

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

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

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

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

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


7

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

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

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

$43, %eax
ret

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


5

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

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

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

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

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


5

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

কারণ এটি সি ++ এর নকশা লক্ষ্যগুলি স্যুট করে।

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

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

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


5

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

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

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

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


3

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

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

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

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

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

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


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

1
আপনি যদিও নিবন্ধগুলিতে সত্যই "স্মৃতি সংরক্ষণ করতে" পারবেন না। আপনি যদি এএইচ এবং আ'লীগকে আপত্তিজনক ব্যবহার করে কিছু অদ্ভুত কিছু করার চেষ্টা না করেন তবে সাধারণ সাধারণ উদ্দেশ্য রেজিস্ট্রেশনে আপনার যে কোনও ভিন্ন মান থাকতে পারে না। স্থানীয় ভেরিয়েবলগুলি প্রায়শই নিবন্ধগুলিতে থাকে এবং প্রয়োজনের প্রয়োজনে কখনই র‍্যামে যায় না।
meneldal
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.