سؤال

MSDN تقول أن الفئة التي سيكون 16 بايت أو أقل سيكون من الأفضل التعامل معها باعتبارها البنية [بحاجة لمصدر].
لماذا هذا ؟
هل هذا يعني أنه إذا كانت البنية هي أكثر من 16 بايت أنها أقل كفاءة من الدرجة أم هو نفسه ؟
كيف يمكنك تحديد ما إذا كان الخاص بك فئة تحت 16 بايت?
ما يقيد البنية التصرف الصف ؟ (إلى جانب عدم السماح parameterless المنشئات)

هل كانت مفيدة؟

المحلول

هناك عدة أجوبة مختلفة على هذا السؤال و هو شخصي قليلا ، ولكن بعض الأسباب أستطيع التفكير هي:

  • البنيات هي قيمة من نوع الطبقات هي نوع مرجع.إذا كنت تستخدم 16 بايت إجمالي تخزين ربما لا يستحق أن إنشاء ذاكرة المراجع (من 4 إلى 8 بايت) لكل واحد.
  • عندما يكون لديك حقا الأشياء الصغيرة ، فإنها غالبا ما تكون دفعت على IL مكدس بدلا من مراجع إلى الكائنات.هذا حقا يمكن أن تصل سرعة بعض التعليمات البرمجية ، كما أنك القضاء على الذاكرة إلغاء مرجعية على المستدعى الجانب.
  • هناك قليلا من اكسترا "زغب" المرتبطة دروس في إلينوي ، وإذا بنية البيانات الخاصة بك صغيرة جدا ، لا شيء من هذا زغب أن تستخدم على أي حال, حتى انها مجرد خردة إضافية لا تحتاج.

أهم فرق بين البنية و فئة ، على الرغم من أن البنيات هي نوع القيمة و الطبقات هي نوع مرجع.

نصائح أخرى

حسب "كفاءة"، وانهم ربما نتحدث عن مقدار الذاكرة الذي يستغرقه لتمثيل فئة أو بنية.

في منصة 32 بت، وتخصيص كائن يتطلب حدا أدنى من 16 بايت. على منصة 64 بت، والحد الأدنى لحجم الجسم هو 24 بايت. لذا، إذا كنت تبحث في ذلك بحتة من مقدار الذاكرة المستخدمة، والبنية التي تحتوي على أقل من 16 بايت من البيانات يكون "أفضل" من الدرجة المقابلة.

ولكن مقدار الذاكرة المستخدمة ليست القصة كلها. أنواع القيمة (البنيات) تختلف اختلافا جوهريا من أنواع المراجع (الطبقات). البنيات يمكن أن يكون غير مريح للعمل مع، ويمكن أن يسبب في الواقع مشاكل الأداء إذا كنت غير دقيق.

والجواب الحقيقي، بطبيعة الحال، هو استخدام أيهما يعمل بشكل أفضل في موقفك. في معظم الحالات، عليك أن تكون أفضل حالا باستخدام الفئات.

وتحقق هذا الرابط، وجدت أنه في واحدة من الإجابات في SO اليوم: . نوع الداخلية لل NET . يمكنك أيضا محاولة البحث SO وغوغلينغ ل "أنواع مرجع مقابل أنواع قيمة" الفروق بين البنيات والطبقات.

<اقتباس فقرة>   <اقتباس فقرة>     

ما يقيد البنية من يتصرف مثل فئة؟

  

وهناك العديد من الاختلافات. لا يمكنك ترث من البنية، على سبيل المثال.

وأنت لا يمكن أن يكون أساليب الافتراضية، بحيث لا يمكنك استخدام البنية لتنفيذ واجهة. يمكن مثيل أساليب في البنيات الوصول إلى حقول خاصة البنية، ولكن بغض النظر عن ذلك يتصرفون مثل الكثير من وظائف "مساعد" auxilirary (لالبنيات الثابتة، وأنها في بعض الأحيان لا تحتاج حتى للوصول إلى البيانات الخاصة). لذلك أجد لها أن تكون لا كما قرب بأنها "قيمة"، كما أساليب الفئة.

وهذا يرجع إلى طريقة مختلفة أن يعالج CLR البنيات والطبقات هذا. البنيات هي أنواع القيمة وهو ما يعني أنهم يعيشون على المكدس وليس في كومة إدارتها. وهي قاعدة جيدة من التجربة للحفاظ على البنيات الصغيرة لأنه بمجرد أن تبدأ تمريرها كوسائط الطريقة التي سوف تحمل النفقات العامة كما يتم نسخ البنيات في مجملها عند تمريرها إلى الأسلوب.

ومنذ الطبقات تمر نسخة من إشارة لالأساليب التي تحمل أقل بكثير النفقات العامة عند استخدامها كوسائط الأسلوب.

وأفضل طريقة لتحديد حجم صفك هو مجموع عدد البايتات المطلوبة من قبل جميع أعضاء صفك بالإضافة إلى اضافي 8 بايت للأشياء علوي CLR (مؤشر كتلة المزامنة والإشارة إلى نوع من موضوع).

والبنيات تختلف عن الطبقات لأنها يتم تخزينها على المكدس، وليس على الكومة. وهذا يعني أنه في كل مرة كنت استدعاء أسلوب مع البنية كمعلمة، يتم إنشاء نسخة وتمريرها إلى الأسلوب. هذا هو السبب في البنيات كبيرة غير فعالة للغاية.

وأود أن تثبط بنشاط لاستخدام البنيات مع ذلك، لأنه يمكن أن يسبب بعض الخلل خفية: على سبيل المثال عند تغيير مجال البنية، وليس على وشك أن ينعكس على الطالب (لأنك غيرت فقط نسخة) - الذي هو السلوك مختلفة تماما عن الطبقات

وحتى 16 بايت وأعتقد أن الحد الأقصى لحجم معقول من البنية، لكنها ما زالت في معظم الحالات، من الأفضل أن يكون فئة. إذا كنت لا تزال ترغب في إنشاء البنية، في محاولة لجعله غير قابل للتغيير على الأقل.

في الذاكرة، والبنية تعقد البيانات مباشرة، في حين أن الطبقة سوف تتصرف أشبه المؤشر. هذا وحده يجعل فارقا مهما، منذ تمرير البنية كمعلمة إلى طريقة سوف تمر قيمها (نسخها على المكدس)، في حين أن الطبقة سيمر الإشارة إلى القيم. إذا كانت بنية كبيرة، سيتم نسخ الكثير من القيم على كل استدعاء الأسلوب. عندما كانت صغيرة حقا نسخ القيم واستخدامها مباشرة من المحتمل أن يكون أسرع من نسخ مؤشر والحاجة إلى الاستيلاء عليها من مكان آخر.

وعن القيود: لا يمكنك تعيين لاغية (على الرغم من أنك يمكن استخدام قيم الفارغة <>) وكان لديك لتهيئة على الفور

ونسخ مثيل البنية يستغرق وقتا أقل من إنشاء مثيل جديد من البيانات الطبقة ونسخ من القديم، ولكن يمكن أن تكون مشتركة حالات الفصل والحالات البنية لا يمكن. وهكذا، "structvar1 = structvar2" يتطلب نسخ المثال البنية الجديد، في حين أن "classvar1 = classvar2" يسمح classvar1 وclassvar2 الرجوع إلى نفس المثيل البنية (دون الحاجة إلى إنشاء واحدة جديدة).

تم تحسين رمز لمعالجة خلق حالات البنية الجديدة ليصل حجمها إلى 16 بايت. يتم التعامل مع البنيات أكبر بكفاءة أقل. البنيات هي الفوز في الحالات التي يكون فيها كل متغير يحمل البنية سيعقد مثيل مستقل (أي ليس هناك سبب لتوقع أن أي اثنين من المتغيرات خاصة تعقد حالات مماثلة)؛ فهي ليست بكثير من فوز (لو انهم فوز على الإطلاق) في الحالات التي يكون فيها العديد من المتغيرات يمكن أن تعقد في نفس مثيل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top