تخطيط الذاكرة في Javascript - التصميم الموجه نحو البيانات مقابل التصميم الموجه للكائنات [مغلق]

StackOverflow https://stackoverflow.com//questions/25041236

سؤال

قادمًا من خلفية C/C++، يعد تخطيط ذاكرة الكائنات فيما يتعلق بتقليل أخطاء ذاكرة التخزين المؤقت أمرًا بالغ الأهمية خاصة عند العمل على وحدات التحكم.غالبًا ما يتم تفضيل التصميم الموجه نحو البيانات على التصميم الموجه للكائنات، وذلك للمساعدة في إبقاء الكائنات ذات الصلة قريبة من بعضها البعض في الذاكرة (خاصة في مجالات الأداء الحرجة).

لقد قمت مؤخرًا ببعض تطوير جافا سكريبت، وأتساءل ما هو الإجماع العام داخل مجتمع جافا سكريبت.

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

لقد قمت بإنشاء حالة اختبار بسيطة (http://jsperf.com/object-vs-data) على jsPerf لمقارنة أداء الطريقتين، وبينما يظهر مكاسب الأداء على Chrome، لا يوجد أي تسريع ملحوظ على Safari.

في جافا سكريبت، هل يجب أن أهتم بتخطيط ذاكرة الكائنات؟أم أن الأمر أقرب إلى "تنفيذه بطريقة واحدة ثم تحسينه إذا لزم الأمر"؟

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

شكرا ~

معلومات إضافية:هذا هو الأساس الذي سأقوم به بتنفيذ الطريقتين في Javascript.يتم تنفيذ حالة اختبار jsPerf أعلاه على هذا النحو.

var objectOriented = [
    { foo: 1, bar: 2 },
    { foo: 3, bar: 4 }
];

var dataOriented = {
    foos: [1, 3],
    bars: [2, 4]
};

// Object-oriented access:
var a = objectOriented[0].bar;

// Data-oriented access:
var b = dataOriented.bars[0];
هل كانت مفيدة؟

المحلول

أنت تعمل من افتراض أساسي أن الكائنات في أعمال JavaScript كما تفعل في C ++. انهم لا.

في C ++، والغرض الأساسي من النوع هو بمثابة التصرف ك "عدسة" على قطعة من الذاكرة. يحدد تخطيط الفصل مباشرة محتويات الذاكرة التي يصف الكائن فيها بطريقة محددة جيدا. مجموعة C / C ++ تتطلب خصيصا تخطيطا خطيا ومستمرا لأنواع متجانسة.

في JavaScript، كائن هو مجموعة من أزواج الاسم / القيمة. صفيف مجرد كائن بممتلكات "طول" خاصة. لاحظ أنه لا يوجد وصف أو تعريف تخطيط الذاكرة هنا. لا يوجد شيء يمنع مترجم JavaScript من صفائف تنفيذ كجدول تجزئة بدلا من جزء خطي من الذاكرة؛ في الواقع، أنا متأكد من أنهم تطبيقات JS التي تفعل ذلك فقط.

تطبيقات JavaScript حرة في وضع الذاكرة ولكنهم يريدون، وليس هناك مراسلات بين أي شيء تفعله في المصدر وما ينتهي فعلا في الجهاز.

بالإضافة إلى ذلك، توجد صفائف جافا سكريبت غير متجانسة، وليس متجانسة. وهذا هو، على افتراض أنه تم وضعه في ذاكرة متجاورة، فإن النوع المكافئ الخاص بك في ج سيكون JSOBJECT **، وليس Int ** (أو تعويم ** أو أيا كان). مجموعة JS هي مجموعة من الإشارات إلى البيانات المخزنة في مكان آخر، لذلك حتى لو كانت المراجع في خط ذاكرة التخزين المؤقت الخاص بك، لن تكون بياناتك.

لذلك، باختصار - هذا النوع من التفكير سيكسبك شيئا سوى الألم. JavaScript هي لغة مستوى أعلى بكثير من C ++، وجزء من ذلك هو التخلي عن عنصر التحكم الذي تستخدمه. هذا النوع من التحسين المنخفض المستوى إذا كان ذلك ممكنا سوف يتم ذلك من قبل المترجم. التركيز على رمز الكتابة مع الخوارزميات الفعالة التي تعبر بشكل طبيعي عن حلكم؛ هذا صعب بما فيه الكفاية كما هو. : -)

نصائح أخرى

نعم.عبثت ببعض الأرقام وحالات الاختبار..

أولاً قمت بإنشاء حالة الاختبار هذه http://jsperf.com/object-vs-array-creation-for-soفي هذه الحالة خلق Object يكون بطريقة أسرع ثم إنشاء Array

ثانيا قمت بإنشاء حالة الاختبار هذه http://jsperf.com/accessing-speedوفي هذا لا يكاد يكون هناك فرق بينهما..

لذا، ما أستنتجه من ملف التعريف هذا هو أن استخدام الكائنات أكثر من المصفوفات سيكون أسرع إذا كان المشروع كذلك ضخمة حقا..لأنه من الحالة الأولى، من الواضح أن إنشاء الكائن أسرع من إنشاء المصفوفة.

لكن..

Javascript هي لغة متطورة وعالية الأداء ولا ينبغي أن تقلق بشأن مثل هذه التحسينات الدقيقة.كل ما عليك التركيز عليه هو دلالات.يجب عليك اختيار الهيكل الذي يصف نيتك بشكل أفضل.

الاختبار في Chrome 36.0.1985.125 على نظام التشغيل Windows NT 6.3

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