OP විසින් යොමු කරන ලද ප්රභවයට යම් විශ්වසනීයත්වයක් ඇත ... නමුත් මයික්රොසොෆ්ට් ගැන කුමක් කිව හැකිද - ව්යුහාත්මක භාවිතය පිළිබඳ ස්ථාවරය කුමක්ද? මම මයික්රොසොෆ්ට් වෙතින් අමතර ඉගෙනීමක් ලබා ගැනීමට උත්සාහ කළෙමි.
වර්ගයේ අවස්ථා කුඩා හා පොදුවේ කෙටිකාලීන හෝ වෙනත් වස්තූන් තුළ පොදුවේ කාවැදී ඇත්නම් පන්තියක් වෙනුවට ව්යුහයක් නිර්වචනය කිරීම සලකා බලන්න.
වර්ගයට පහත සඳහන් සියලු ලක්ෂණ නොමැති නම් ව්යුහයක් නිර්වචනය නොකරන්න:
- එය තාර්කිකව ප්රාථමික වර්ග වලට සමාන තනි අගයක් නියෝජනය කරයි (නිඛිල, ද්විත්ව සහ යනාදිය).
- එහි උදාහරණ ප්රමාණය බයිට් 16 ට වඩා කුඩාය.
- එය වෙනස් කළ නොහැකි ය.
- එය නිතර කොටු කිරීමට අවශ්ය නොවනු ඇත.
මයික්රොසොෆ්ට් නිරන්තරයෙන් එම නීති උල්ලං lates නය කරයි
හරි, කෙසේ වෙතත් # 2 සහ # 3. අපගේ ආදරණීය ශබ්දකෝෂයට අභ්යන්තර ව්යුහ 2 ක් ඇත:
[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 සමාව දිය හැකි බැවින් # 4 බොහෝ විට ගැටලුවක් නොවනු ඇත. ඔබ බොක්සිං ව්යුහයක් සොයා ගන්නේ නම්, ඔබේ ගෘහ නිර්මාණ ශිල්පය ගැන නැවත සිතා බලන්න.
මයික්රොසොෆ්ට් මෙම ව්යුහයන් භාවිතා කරන්නේ මන්දැයි සොයා බලමු:
- සෑම ව්යුහයක්ම,
Entry
සහ Enumerator
, තනි අගයන් නියෝජනය කරයි.
- වේගය
Entry
ශබ්ද කෝෂ පන්තියෙන් පිටත කිසි විටෙකත් පරාමිතියක් ලෙස සම්මත නොවේ. වැඩිදුර විමර්ශන වලින් පෙනී යන්නේ IEnumerable ක්රියාත්මක කිරීම තෘප්තිමත් කිරීම සඳහා, සංඛ්යා ලේඛකයෙකු Enumerator
ඉල්ලා සිටින සෑම අවස්ථාවකම එය පිටපත් කරන ව්යුහය ශබ්දකෝෂය භාවිතා කරන බවයි ... අර්ථවත් කරයි.
- ශබ්ද කෝෂ පන්තියට අභ්යන්තරය.
Enumerator
ශබ්දකෝෂය ගණන් කළ නොහැකි බැවින් IEnumerator අතුරුමුහුණත ක්රියාත්මක කිරීමට සමාන ප්රවේශයක් තිබිය යුතුය - උදා: IEnumerator getter.
යාවත්කාලීන කිරීම - ඊට අමතරව, ව්යුහයක් අතුරුමුහුණතක් ක්රියාත්මක කරන විට - ගණන් ගැනීමේ යන්ත්රය මෙන් - සහ එය ක්රියාත්මක කරන ලද වර්ගයට දැමූ විට, ව්යුහය විමර්ශන වර්ගයක් බවට පත් වන අතර එය ගොඩට ගෙන යනු ලැබේ. ශබ්දකෝෂය පන්තියට අභ්යන්තර, ගණන් වේ තවමත් අගය වර්ගය. කෙසේ වෙතත්, ක්රමයක් ඇමතූ විගසම GetEnumerator()
විමර්ශන වර්ගයක් IEnumerator
ආපසු ලබා දෙනු ලැබේ.
අප මෙහි නොදකින දෙය නම් ව්යුහයන් වෙනස් කළ නොහැකි ලෙස තබා ගැනීමට හෝ නිදර්ශන ප්රමාණය බයිට් 16 ක් හෝ ඊට අඩු ප්රමාණයක් පවත්වා ගැනීමට අවශ්ය ඕනෑම උත්සාහයක් හෝ සාක්ෂියක්:
- ඉහත ව්යුහයන්හි කිසිවක් ප්රකාශ කර නැත
readonly
- වෙනස් කළ නොහැක
- මෙම ව්යුහයේ ප්රමාණය බයිට් 16 ට වඩා වැඩි විය හැකිය
Entry
(සිට undetermined ජීවිත කාලය ඇත Add()
කිරීමට, Remove()
, Clear()
, හෝ කැළි කසළ);
සහ ... 4. ව්යුහයන් දෙකම TKey සහ TValue ගබඩා කර ඇති අතර ඒවා අප දන්නා පරිදි විමර්ශන වර්ග විය හැකිය (ප්රසාද තොරතුරු එකතු කරන ලදි)
හැෂ් යතුරු තිබියදීත්, ශබ්දකෝෂ අර්ධ වශයෙන් වේගවත් බැවින් ව්යුහයක් ස්ථාපනය කිරීම විමර්ශන වර්ගයකට වඩා ඉක්මන් වේ. මෙන්න, මට Dictionary<int, int>
අනුක්රමිකව වැඩි කරන ලද යතුරු සමඟ අහඹු සංඛ්යා 300,000 ක් ගබඩා කර ඇත .
ධාරිතාව: 312874 මතක
ප්රමාණය: බයිට් 2660827
සම්පූර්ණ කරන ලද
ප්රමාණය: 5ms පිරවීමට ගතවන කාලය: 889ms
ධාරිතාව : අභ්යන්තර අරාවට පෙර ලබා ගත හැකි මූලද්රව්ය ගණන ප්රමාණය වෙනස් කළ යුතුය.
MemSize : ශබ්ද කෝෂය මතක ධාරාවකට අනුක්රමණය කිරීමෙන් සහ බයිට් දිගක් ලබා ගැනීමෙන් තීරණය වේ (අපගේ අරමුණු සඳහා ප්රමාණවත් තරම් නිවැරදි).
සම්පූර්ණ කළ ප්රමාණය: අභ්යන්තර අරාව මූලද්රව්ය 150862 සිට මූලද්රව්ය 312874 දක්වා ප්රමාණය වෙනස් කිරීමට ගතවන කාලය. සෑම මූලද්රව්යයක්ම අනුපිළිවෙලින් පිටපත් කර Array.CopyTo()
ඇති බව ඔබ වටහා ගත් විට, එය එතරම් අවුල් සහගත නොවේ.
පිරවීම සඳහා ගතවන මුළු කාලය : ලොග් වීම සහ OnResize
මා ප්රභවයට එකතු කළ සිදුවීමක් හේතුවෙන් පිළිගත හැකි ය; කෙසේ වෙතත්, මෙහෙයුමේදී 15 වතාවක් ප්රතිප්රමාණනය කරන අතරම 300k පූර්ණ සංඛ්යා පිරවීම තවමත් සිත් ඇදගන්නා සුළුය. කුතුහලයෙන් යුතුව, මා දැනටමත් ධාරිතාව දැන සිටියේ නම් පිරවීමට ගතවන කාලය කොපමණ වේද? 13ms
ඉතින්, දැන්, Entry
පංතියක් නම් කුමක් කළ යුතුද? මෙම වේලාවන් හෝ ප්රමිතික ඇත්ත වශයෙන්ම එතරම් වෙනස් වේද?
ධාරිතාව: 312874 මතක
ප්රමාණය: බයිට් 2660827
සම්පූර්ණ කරන ලද
ප්රමාණය: 26ms පිරවීමට ගතවන මුළු කාලය: මීටර් 964
නිසැකවම, විශාල වෙනස වන්නේ ප්රමාණය වෙනස් කිරීමයි. ධාරිතාවයෙන් ශබ්දකෝෂය ආරම්භ කරන්නේ නම් යම් වෙනසක් තිබේද? සැලකිලිමත් වීමට ප්රමාණවත් නොවේ ... 12ms .
සිදුවන්නේ, 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
විමර්ශන වර්ගයක් ලෙස ආරම්භ කිරීමට මට සිදු වූ හේතුව MSDN: ව්යුහ නිර්මාණයෙන් සොයාගත හැකිය . කෙටියෙන්:
ව්යුහයක් සඳහා පෙරනිමි ඉදිකිරීම්කරුවෙකු ලබා නොදෙන්න.
ව්යුහයක් පෙරනිමි ඉදිකිරීම්කරුවෙකු නිර්වචනය කරන්නේ නම්, ව්යුහයේ අරා නිර්මාණය කරන විට, පොදු භාෂා ධාවන කාලය සෑම අරා මූලද්රව්යයකම පෙරනිමි ඉදිකිරීම්කරු ස්වයංක්රීයව ක්රියාත්මක කරයි.
C # සම්පාදකයා වැනි සමහර සම්පාදකයින් ව්යුහයන්ට පෙරනිමි ඉදිකිරීම්කරුවන් වීමට ඉඩ නොදේ.
එය ඇත්ත වශයෙන්ම තරමක් සරල වන අතර අපි අසිමොව්ගේ රොබෝ තාක්ෂණය පිළිබඳ නීති තුනෙන් ණයට ගන්නෙමු :
- ව්යුහය භාවිතා කිරීමට ආරක්ෂිත විය යුතුය
- මෙය # 1 රීතිය උල්ලං would නය නොකරන්නේ නම්, ව්යුහය එහි කාර්යය කාර්යක්ෂමව ඉටු කළ යුතුය
- රීතිය # 1 තෘප්තිමත් කිරීම සඳහා එහි විනාශය අවශ්ය නොවන්නේ නම්, ව්යුහය එහි භාවිතයේදී නොවෙනස්ව පැවතිය යුතුය
... අප මෙයින් ඉවත් කරන්නේ කුමක් ද : කෙටියෙන් කිවහොත්, වටිනාකම් වර්ග භාවිතා කිරීම සම්බන්ධයෙන් වගකිව යුතු ය. ඒවා ඉක්මන් හා කාර්යක්ෂම වන නමුත් නිසි ලෙස නඩත්තු නොකළහොත් බොහෝ අනපේක්ෂිත හැසිරීම් ඇති කිරීමේ හැකියාව ඇත (එනම් නොදැනුවත්වම පිටපත්).
System.Drawing.Rectangle
මෙම නීති තුනම උල්ලං lates නය කරයි.