ওপি দ্বারা সূচিত উত্সটির কিছুটা বিশ্বাসযোগ্যতা রয়েছে ... তবে মাইক্রোসফ্টের কী - স্ট্রাক্ট ব্যবহারের বিষয়ে অবস্থান কী? আমি মাইক্রোসফ্টের কাছ থেকে কিছু অতিরিক্ত শিখতে চেয়েছি এবং আমি যা পেয়েছি তা এখানেই রয়েছে:
শ্রেণীর পরিবর্তে কোনও কাঠামো সংজ্ঞায়িত করার বিষয়ে বিবেচনা করুন যদি ধরণের উদাহরণগুলি ছোট এবং সাধারণত স্বল্প-কালীন হয় বা সাধারণত অন্য বস্তুতে এম্বেড থাকে।
ধরণের নিম্নলিখিত বৈশিষ্ট্যগুলির মধ্যে না থাকলে কোনও কাঠামো সংজ্ঞায়িত করবেন না:
- এটি যৌক্তিকভাবে একক মানকে উপস্থাপিত করে, আদিম ধরণের (পূর্ণসংখ্যা, ডাবল এবং আরও কিছু) অনুরূপ।
- এটির একটি আকারের আকার 16 বাইটের চেয়ে ছোট।
- এটি অপরিবর্তনীয়।
- এটি ঘন ঘন বক্স করতে হবে না।
মাইক্রোসফ্ট নিয়মিতভাবে এই নিয়মগুলি লঙ্ঘন করে
ঠিক আছে, যাই হোক না কেন # 2 এবং # 3। আমাদের প্রিয় অভিধানটিতে দুটি অভ্যন্তরীণ স্ট্রাক্ট রয়েছে:
[StructLayout(LayoutKind.Sequential)] // default for structs
private struct Entry //<Tkey, TValue>
{
// View code at *Reference Source
}
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator :
IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable,
IDictionaryEnumerator, IEnumerator
{
// View code at *Reference Source
}
* রেফারেন্স উত্স
'জনিক্যান্টকোড ডট কম' উত্সটি 4 টির মধ্যে 3 পেয়েছে - যেহেতু # 4 সম্ভবত এটি কোনও সমস্যা হবে না quite যদি আপনি নিজেকে স্ট্রাক্ট বক্সিং মনে করেন তবে আপনার আর্কিটেকচারটি পুনর্বিবেচনা করুন।
মাইক্রোসফ্ট কেন এই স্ট্রাক্ট ব্যবহার করবে তা দেখুন:
- প্রতিটি কাঠামো,
Entry
এবং Enumerator
, একক মান উপস্থাপন করে।
- দ্রুততা
Entry
অভিধান ক্লাসের বাইরে কখনও প্যারামিটার হিসাবে পাস হয় না। আরও তদন্তে দেখা যায় যে আইনুনামেবলের বাস্তবায়ন সন্তুষ্ট করার জন্য, অভিধানটি সেই কাঠামোটি ব্যবহার করে Enumerator
যা এটি প্রতিবার কোনও গণকের অনুরোধের সময় অনুলিপি করে ... তা বোঝায়।
- অভিধান ক্লাসে অভ্যন্তরীণ।
Enumerator
অভিধানটি গণনাযোগ্য, কারণ এটি আইকনমেন্টার ইন্টারফেস বাস্তবায়নের সমান অ্যাক্সেসিবিলিটি থাকতে পারে - যেমন আইইনুমেরেটর প্রাপ্তি।
আপডেট - এ ছাড়াও, উপলব্ধি করুন যে যখন স্ট্রাক্ট একটি ইন্টারফেস প্রয়োগ করে - যেমন এনুমুরেটর করে - এবং প্রয়োগকৃত ধরণেরটিতে ফেলে দেওয়া হয়, তখন কাঠামোটি একটি রেফারেন্স টাইপ হয়ে যায় এবং তাকে গাদা হয়ে যায়। অভ্যন্তরীণ অভিধান ক্লাসের মধ্যেই গণনাকারী হয় এখনও একটি মান প্রকার। তবে কোনও পদ্ধতি কল করার সাথে সাথে GetEnumerator()
একটি রেফারেন্স-টাইপ IEnumerator
ফিরে আসে।
আমরা এখানে যা দেখছি না তা হ'ল স্ট্রাক্টগুলি অপরিবর্তনীয় রাখার জন্য প্রয়োজনীয়তার প্রয়াস বা প্রমাণ যা কেবলমাত্র 16 বাইট বা তার চেয়ে কম আকারের উদাহরণ বজায় রাখতে হবে:
- উপরের স্ট্রাইকগুলির কোনও কিছুই ঘোষণা করা হয়নি
readonly
- স্থাবর নয়
- এই কাঠামোর আকার 16 বাইটের বেশি হতে পারে
Entry
একটি অনির্ধারিত জীবনকাল আছে (থেকে Add()
, এর Remove()
, Clear()
অথবা আবর্জনা সংগ্রহ);
এবং ... ৪. উভয় স্ট্রাক্টই TKey এবং TValue স্টোর করে, যা আমরা সবাই জানি রেফারেন্স টাইপ হওয়ার পক্ষে যথেষ্ট সক্ষম (যুক্ত বোনাস তথ্য)
তবুও, হ্যাশ কীগুলি সত্ত্বেও, অভিধানগুলি অংশে দ্রুত are এখানে আমার কাছে একটি Dictionary<int, int>
ক্রমবর্ধমান কীগুলির সাথে 300,000 এলোমেলো পূর্ণসংখ্যার সঞ্চয় রয়েছে।
ক্ষমতা: 312874
মেমসাইজ: 2660827 বাইটস
সম্পূর্ণ পুনরায় আকার: 5 এমএস পূরণের
মোট সময়: 889ms
ক্ষমতা : অভ্যন্তরীণ অ্যারেটিকে পুনরায় আকার দেওয়ার আগে প্রয়োজনীয় উপাদানের সংখ্যা।
মেমসাইজ : অভিধানকে মেমোরিস্ট্রিমে সিরিয়ালাইজ করে এবং একটি বাইট দৈর্ঘ্য (আমাদের উদ্দেশ্যগুলির জন্য যথেষ্ট সঠিক) পেয়ে নির্ধারিত।
সম্পূর্ণ আকার পরিবর্তন: 150862 উপাদান থেকে 312874 উপাদানগুলিতে অভ্যন্তরীণ অ্যারেটিকে পুনরায় আকার দিতে সময় লাগে। যখন আপনি দেখেন যে প্রতিটি উপাদান ক্রমানুসারে অনুলিপি করা হয় Array.CopyTo()
, এটি খুব জঞ্জাল নয়।
ভরাট করার মোট সময় : লগিংয়ের কারণে স্বীকৃতভাবে স্কিউড এবং উত্সটিতে OnResize
আমি একটি ইভেন্ট যুক্ত করেছি; তবে, অপারেশন চলাকালীন 15 বার পুনরায় আকার দেওয়ার সময় 300k পূর্ণসংখ্যা পূরণ করতে এখনও চিত্তাকর্ষক। মাত্র কৌতূহলের বাইরে, যদি আমি ইতিমধ্যে ক্ষমতাটি জানতাম তবে মোট পূরণের সময়টি কত হবে? 13ms
সুতরাং, এখন, যদি Entry
একটি ক্লাস হত? এই সময় বা মেট্রিকস কি সত্যিই অনেক আলাদা হবে?
ক্ষমতা: 312874
মেমসাইজ: 2660827 বাইট
সম্পূর্ণ পুনরায় আকার: 26 মিম পূরণের
মোট সময়: 964ms
স্পষ্টতই, বড় পার্থক্যটি আকার পরিবর্তন করতে হয়। সক্ষমতা দিয়ে অভিধান শুরু করা থাকলে কোনও পার্থক্য? ... 12 মিমি নিয়ে উদ্বিগ্ন হওয়ার জন্য যথেষ্ট নয় ।
যা ঘটে তা হ'ল কারণ Entry
এটি একটি কাঠামো, এটির জন্য কোনও রেফারেন্স টাইপের মতো আরম্ভের প্রয়োজন হয় না। এটি সৌন্দর্য ধরণ এবং মান ধরণের নিষ্ক্রিয় উভয়ই। Entry
একটি রেফারেন্স টাইপ হিসাবে ব্যবহার করতে , আমাকে নিম্নলিখিত কোডটি প্রবেশ করানো হয়েছিল:
/*
* Added to satisfy initialization of entry elements --
* this is where the extra time is spent resizing the Entry array
* **/
for (int i = 0 ; i < prime ; i++)
{
destinationArray[i] = new Entry( );
}
/* *********************************************** */
Entry
রেফারেন্স টাইপ হিসাবে আমাকে প্রতিটি অ্যারের উপাদানটি সূচনা করার কারণটি এমএসডিএন: স্ট্রাকচার ডিজাইনে পাওয়া যাবে । সংক্ষেপে:
কোনও কাঠামোর জন্য কোনও ডিফল্ট কনস্ট্রাক্টর সরবরাহ করবেন না।
যদি কোনও কাঠামো একটি ডিফল্ট কনস্ট্রাক্টরকে সংজ্ঞায়িত করে, যখন কাঠামোর অ্যারে তৈরি করা হয়, সাধারণ ভাষা রানটাইম স্বয়ংক্রিয়ভাবে প্রতিটি অ্যারের উপাদানটিতে ডিফল্ট কনস্ট্রাক্টরকে কার্যকর করে।
কিছু সংকলক যেমন সি # সংকলক স্ট্রাকচারকে ডিফল্ট কনস্ট্রাক্টর থাকতে দেয় না।
এটি আসলে বেশ সহজ এবং আমরা অসিমভের রোবোটিক্সের তিনটি আইন থেকে willণ নেব :
- কাঠামো অবশ্যই ব্যবহারের জন্য নিরাপদ থাকতে হবে
- স্ট্রাক্ট অবশ্যই অবশ্যই তার কার্য সম্পাদন করবে, যদি না এটি # 1 বিধি লঙ্ঘন করে
- কাঠামোটি ব্যবহারের সময় অবশ্যই অক্ষত থাকতে হবে যতক্ষণ না এর ধ্বংসের প্রয়োজন হয় # 1 বিধি পূরণ করার জন্য
... আমরা এ থেকে কী নেব : সংক্ষেপে, মান ধরণের ব্যবহারের সাথে দায়বদ্ধ। এগুলি দ্রুত এবং দক্ষ, তবে সঠিকভাবে রক্ষণাবেক্ষণ না করা হলে (যেমন অনিচ্ছাকৃত অনুলিপিগুলি) অনেকগুলি অপ্রত্যাশিত আচরণের সক্ষমতা রয়েছে।
System.Drawing.Rectangle
এই তিনটি নিয়ম লঙ্ঘন করে।