ইথেরিয়াম সলিডিটি: মেমরি বনাম স্টোরেজ এবং কখন তাদের ব্যবহার করবেন

কেউ আমাকে গিথুবে জিজ্ঞাসা করেছিলেন যে আমাদের নীচের সরলীকৃত কোড স্নিপেটে স্টোরেজ বা মেমরি কীওয়ার্ডটি ব্যবহার করা উচিত:

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

সলিডির ডকুমেন্টেশন অনুসারে, এই দুটি কীওয়ার্ড রেফারেন্স টাইপের জন্য যেখানে ব্যবহৃত হয়

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

ইভিএম (ইথেরিয়াম ভার্চুয়াল মেশিন) কোথায় ডেটা সঞ্চয় করে তা দেখার বিষয়টি এখন গুরুত্বপূর্ণ:

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

সবচেয়ে গুরুত্বপূর্ণভাবে,

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

এখানেই এটি বিভ্রান্ত হয়ে পড়ে:

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

পুনরুদ্ধার করতে, ডকুমেন্টেশনে ফিরে যান:

জোরপূর্বক ডেটা অবস্থান:
বাহ্যিক ফাংশনগুলির পরামিতি (প্রত্যাবর্তন নয়): ক্যালডাটা
* রাষ্ট্রের ভেরিয়েবল: স্টোরেজ
ডিফল্ট ডেটা অবস্থান:
ফাংশনগুলির পরামিতি (এছাড়াও ফিরে): মেমরি
অন্যান্য সমস্ত স্থানীয় ভেরিয়েবল: স্টোরেজ

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

উপার্জনকারীদের জন্য উপরে বর্ণনামূলক চুক্তিতে ফিরে যান:

ফাংশন getUsingStorage (uint _itemIdx)
প্রকাশ্য
// গ্যাস অনুমানের জন্য অ-দর্শনতে সেট করুন
// দেখুন
রিটার্ন (uint)
{
আইটেম স্টোরেজ আইটেম = আইটেম [_itemIdx];
রিটার্ন আইটেম। ইউনিটস;
}
ফাংশন getUsingMemory (uint _itemIdx)
প্রকাশ্য
// গ্যাস অনুমানের জন্য অ-দর্শনতে সেট করুন
// দেখুন
রিটার্ন (uint)
{
আইটেম মেমরি আইটেম = আইটেম [_itemIdx];
রিটার্ন আইটেম। ইউনিটস;
}

উভয় ফাংশন একই ফলাফল প্রদান করে, getUsingMemory ব্যতীত একটি নতুন ভেরিয়েবল তৈরি হয় এবং এর ফলে আরও বেশি গ্যাস ব্যবহৃত হয়:

// getUsingStorage
"গ্যাসযুক্ত": 21849
// getUsingMemory
"গ্যাসযুক্ত": 22149,

অন্যদিকে, সেটটারদের জন্য:

ফাংশন অ্যাড আইটেম ইউজিং স্টোরেজ (uint _itemIdx, uint _units)
প্রকাশ্য
{
আইটেম স্টোরেজ আইটেম = আইটেম [_itemIdx];
আইটেম.উইনটস + = _ ইউনিট;
}
ফাংশন অ্যাড আইটেমস ইউজিং মেমোরি (uint _itemIdx, uint _units)
প্রকাশ্য
// গ্যাস অনুমানের জন্য অ-দর্শনতে সেট করুন
// দেখুন
{
আইটেম মেমরি আইটেম = আইটেম [_itemIdx];
আইটেম.উইনটস + = _ ইউনিট;
}

কেবল অ্যাড আইটেমসিং স্টোরেজ স্টেট ভেরিয়েবল পরিবর্তন করেছে (আরও বেশি গ্যাস গ্রাস করছে):

// addItemUsingStorage
// `ইউনিট`` আইটেমগুলিতে পরিবর্তন `
"গ্যাসযুক্ত": 27053,
// addItemUsingMemory
// `ইউনিট`` আইটেমগুলিতে পরিবর্তিত হয় না `
"গ্যাসযুক্ত": 22287,

সুতরাং বন্ধ করার জন্য, দখলগুলি হ'ল:

  1. মেমরি এবং স্টোরেজ উল্লেখ করে যে চলকটি কোন ডেটা অবস্থানের সাথে সম্পর্কিত
  2. ফাংশনে নতুনভাবে স্টোরেজ তৈরি করা যায় না। কোনও ক্রিয়াকলাপে কোনও স্টোরেজ রেফারিং ভেরিয়েবল সর্বদা চুক্তির স্টোরেজে প্রাক-বরাদ্দকৃত ডেটা টুকরোকে উল্লেখ করে (রাজ্য ভেরিয়েবল)। কোন রূপান্তর ফাংশন কল পরে স্থায়ী।
  3. মেমরি কেবলমাত্র একটি ফাংশনে তৈরি করা যেতে পারে। এটি হয় নতুনভাবে ইনস্ট্যান্টিয়েটেড জটিল ধরণের যেমন অ্যারে / স্ট্রাক্ট (উদাঃ নতুন ইনট [...]) এর মাধ্যমে বা স্টোরেজ রেফারেন্সড ভেরিয়েবল থেকে অনুলিপি করা যেতে পারে।
  4. যেমন ফাংশন প্যারামিটারগুলির মাধ্যমে অভ্যন্তরীণভাবে রেফারেন্সগুলি পাস করা হয়, মনে রাখবেন সেগুলি মেমোরিতে ডিফল্ট হয় এবং যদি ভেরিয়েবলটি স্টোরেজে থাকে তবে এটি একটি অনুলিপি তৈরি করবে এবং কোনও পরিবর্তন স্থির থাকবে না।

তথ্যসূত্র: