مجموعة ديناميكية مقابل قائمة مرتبطة


الاجابه 1:

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

المصفوفة هي قطعة متجاورة من الذاكرة. عندما تفعل

int * array = (int *) malloc (10 * sizeof (int)) ؛

تحصل على عنوان كتلة من 10 أعداد صحيحة جنبًا إلى جنب مخصصة لاستخدامك.

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

* الصفيف هو العنصر الأول* (الصفيف + 1) هو الثاني* (الصفيف + 2) هو الثالث ..الخأو ما يعادل ذلك ، باستخدام بعض بناء الجملة مستوى أعلى:صفيف [0]صفيف [1]صفيف [2]

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

إذا كانت عالية الأداء وأسهل في العمل معها ، فما هو الجانب السلبي على الأرض؟

أتذكر القليل عن كونها مواقع ذاكرة متجاورة؟ ما مقدار الذاكرة المتوفرة لديك؟ دعنا نقول 10 العربات. تقوم بتشغيل برنامجك ويخصص 10 مصفوفات ، حجم كل منها 700 ميجابايت. لذلك فقد خصصت ما مجموعه 7 جيجابايت ولديك 3 جيجابايت من اليسار؟ لماذا لا تخصص الباقي في صفيف جديد 3 جيجابايت. جربها. عفوًا ، حدث خطأ في الذاكرة من malloc !! لكن لماذا؟؟

نعم ، لا يزال لديك 3 غيغابايت متاحة ولكن ليست متاحة بشكل متواصل! قد يبدو تخطيطك كما يلي:

700 ميجابايت مخصصة - 300 ميجابايت مجانية - 700 مخصصة - 300 مجانًا - إلخ

كما ترى ، الذاكرة المجزأة مجزأة بين كتل الذاكرة المستعملة!

حجم الذاكرة المتاحة لصفيف الوحش أكثر تعقيدا. إنها وظيفة الذاكرة المتاحة وتخطيط تخصيص الذاكرة. الحد الأقصى للصفيف الذي يمكنك تخصيصه الآن سيكون 300 ميجابايت وليس 3 جيجابايت !!

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

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

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

بالنسبة لكميات كبيرة من البيانات ، ستحتاج إلى استخدام كل من الذاكرة المتجاورة والمرتبطة.


الاجابه 2:

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

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

ملاحظة: إذا كنت لا تهتم بترتيب العناصر ، فهناك خدعة لإزالة العناصر في المنتصف لا تحرك جميع العناصر - فقط قم بتبديل العنصر الذي تريد إزالته بالعنصر الأخير ، ثم احذف العنصر الأخير (حذف في النهاية غالبًا ما يتم فقط تحديث مؤشر التعبئة).


الاجابه 3:

دعني أعطيك قصة بسيطة.

يتم حفظ جهات الاتصال في هاتفك في شكل قائمة مرتبطة.

Explanation: للحظة ضع في اعتبارك استخدام المصفوفات لنفس الغرض. تخيل أن لدينا بعض الاتصالات المحفوظة مثل Arun و Beiber و Raj و Sushant و Tarun. لديك صفيف حجم 1000 وهو الحد الأقصى لا. من البيانات التي يمكن أن يقوم هاتفك بتخزينها ، الآن إذا حاولت حفظ جهة اتصال جديدة باسم Dhawan ، قائمة العمليات التي يجب القيام بها:

  • قم بتحويل جميع العناصر بعد خطوة "Beiber" نحو اليمين لخلق مساحة لتخزين "Dhawan" ، حيث يتم تخزين جهات الاتصال بترتيبها.
  • عد إلى الموضع الذي بدأت منه في التحول وإدراج الذوان.

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

أتمنى أن يساعدك هذا :)


الاجابه 4:

تفضل القوائم المرتبطة على المصفوفات عندما:

أ) أنت بحاجة إلى عمليات الإدراج / الحذف في الوقت الثابت من القائمة (كما هو الحال في الحوسبة في الوقت الفعلي حيث تكون إمكانية التنبؤ بالوقت بالغة الأهمية)

ب) لا تعرف عدد العناصر الموجودة في القائمة. مع المصفوفات ، قد تحتاج إلى إعادة إعلان الذاكرة ونسخها إذا زاد حجم المصفوفة

ج) لا تحتاج إلى وصول عشوائي إلى أي عناصر

د) تريد أن تكون قادرًا على إدراج عناصر في منتصف القائمة (مثل قائمة انتظار الأولوية)

يفضل استخدام المصفوفات عندما:

أ) تحتاج إلى وصول مفهرس / عشوائي للعناصر

ب) أنت تعرف عدد العناصر في الصفيف مسبقًا بحيث يمكنك تخصيص مقدار الذاكرة الصحيح للصفيف

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

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

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

ينطوي أحد أهم قرارات تصميم التطبيق على بنية البيانات التي يجب استخدامها. تعد المصفوفات والقوائم المرتبطة من بين هياكل البيانات الأكثر شيوعًا ، وكل منها قابل للتطبيق في مواقف مختلفة.

تم تصميم المصفوفات والقوائم المرتبطة لتخزين عناصر متعددة ، غالبًا من نفس النوع. وفقًا لموسوعة Computer Desktop Encyclopedia ، فإن المصفوفة هي ترتيب منظم لعناصر البيانات التي يتم الوصول إليها من خلال مؤشراتها المرجعية. القائمة المرتبطة هي مجموعة من العناصر ، يحتوي كل منها على مؤشر يشير إلى العنصر التالي.

ستستكشف هذه المقالة خصائص كل هيكل لمساعدتك في تحديد أيهما أفضل لتطبيقك.

يمكن أن تكون صفيفات التحجيم أحادية البعد أو متعددة الأبعاد ، وفقًا لمتطلباتك. على سبيل المثال ، يمكنك استخدام مصفوفة أحادية البعد لتخزين درجات جميع الطلاب في الفصل لاختبار واحد. سيكون من الأفضل وضع مجموعة متعددة الأبعاد لتخزين درجات جميع الطلاب لجميع الاختبارات طوال الفصل الدراسي. يقدم الشكل أ مثالاً لصفيف أحادي البعد ، ويعرض الشكل ب صفيفًا متعدد الأبعاد.

الشكل أ

صفيف أحادي البعد

الشكل ب

صفيف متعدد الأبعاد

في الشكل ب ، قد يتم حساب متوسط ​​الدرجات عن طريق الاختبار (عبر) ، أو بواسطة الطالب (لأسفل) ، أو حسب الفصل الدراسي (مجموعة كاملة) ، بينما يتم الاحتفاظ بكل درجة فريدة.

على النقيض من المصفوفات ، تعد القوائم المرتبطة بطبيعتها أحادية البعد. يمكن أن تكون قوائم مرتبطة بشكل فردي ، كما هو موضح في الشكل C ، حيث يمكن اجتياز القائمة في اتجاه واحد فقط ، أو قوائم مرتبطة بشكل مزدوج ، كما هو الحال في الشكل D ، حيث يشير كل عنصر إلى كل من العنصر السابق والعنصر التالي في القائمة.

الشكل ج

قائمة مرتبطة بشكل فردي

الشكل د

قائمة مرتبطة مزدوجة

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

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

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

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

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

باستخدام Java ، تقدم فئة القائمة المرتبطة المقدمة قائمة مرتبطة مفهرسة تدعم جميع طرق القائمة القياسية (الأعلى ، التالي ، السابق ، وما إلى ذلك) بالإضافة إلى العملية المفهرسة. تسمح أساليب indexOf () و get () و set () بالوصول الشبيه بالمصفوفة إلى عناصر القائمة. بالإضافة إلى ذلك ، توفر Java فئة ArrayList التي تمثل تطبيق صفيف يمكن تغيير حجمه لفئة القائمة. تدعم كلتا هاتين الفئتين طرقًا لإعادة المصفوفات الحقيقية من تمثيلات القوائم الخاصة بهم.

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

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

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


الاجابه 5:

تُظهر الرسوم البيانية مقارنة تعقيد الفضاء بين ArrayList و LinkedList ولكن في العالم الواقعي ستكون أقل إزعاجًا بشأن تعقيد الفضاء مقارنةً بتعقيد الوقت ، لذلك دعونا نرى مقارنة تعقيد الوقت للعمليات المختلفة.

  • الإدراج أو الإزالة في البداية أو في المنتصف هو عملية وقت محدد في LinkedList أثناء وجودك في ArrayList عندما تريد الإدراج أو الإزالة من الوسط ، فيجب عليك نقل جميع العناصر بعد إزالة العنصر أو إدراجه في أسوأ حالة تعقيد لحالة O ( ن).
  • الإدراج في نهاية هذه العملية أيضًا له تعقيد زمني مترابط لـ LinkedList وأسوأ تعقيد زمني O (n) لـ ArrayList لأن حجم ArrayList ديناميكيًا مما يعني أن حجم ArrayList يتم إصلاحه في البداية كلما كان حجم ArrayList بحاجة إلى زيادة أكثر من سعته جميع يتم نسخ عناصر ArrayList الحالية إلى ArrayList الجديد الذي يبلغ حجمه 1.5 مرة أكثر. لكن متوسط ​​تعقيد هذه العملية أقل بكثير.
  • يعد الوصول إلى العنصر عملية زمنية ثابتة لـ ArrayList لأنه يمكنك الوصول إلى أي عنصر باستخدام الفهرس الخاص به بينما في LinkedList تحتاج إلى التكرار عبر القائمة بأكملها للعثور على العنصر ، لذا فإن أسوأ وقت لتعقيد الحالة سيكون O (n).

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

تعديل: - فيما يلي الصورة التي كانت موجودة من قبل في تفاصيل السؤال.


الاجابه 6:

في مقابلة أو مهمة أكاديمية حيث يجبرك شخص ما على ذلك.

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

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

بالنسبة لي ، الإعداد الافتراضي هو مجموعة ديناميكية متجاورة قديمة الطراز. لذا ضع القائمة في C # والمتجه في cpp / Stl.

لم يكن هذا عنق الزجاجة الذي كان يجب ترقيته إلى شيء أفضل بشكل مقارب.

أنا لا أقول أنه ليس لديهم مكان ، بل يجب أن تفهم حقًا احتياجات تطبيقك. إذا كنت تعمل على بعض سيناريوهات الإنتاجية العالية / المتزامنة / الضخمة التي تحتاج إليها ، فستعرف. خلاف ذلك ، ربما تكون على حق 99 ٪ من الوقت إذا كنت لا تستخدم القوائم المرتبطة.


الاجابه 7:

“أنا أعرف مدى تعقيد العمليات المختلفة ومقارناتها. ولكن على الرغم من كل ذلك ، لا يمكنني معرفة الفوائد الحقيقية لهذا الأمر ".

هذا أربكني. إذا كنت تعرف مقارنات التعقيد ، فيجب أن تتجادل حول سبب اعتقادك أن هذه التعقيدات لا تترجم إلى فوائد في العالم الحقيقي.

  1. إذا كنت بحاجة إلى الاستعلام عن البيانات التي تم فرزها بشكل متكرر ، فستكون العملية أوامر بحجم أسرع على صفيف من قائمة مرتبطة ، لأنه يمكنك إجراء بحث ثنائي سريع.
  2. لنفترض أنك نفذت عملية `get` التي تُرجع العنصر في فهرس. لنفترض أنك فعلت ذلك مليون مرة ، في قائمة تحتوي على مليون إدخال ، يتم توزيع مؤشرات الاستعلام بشكل عشوائي من 0 إلى 999،999. للحصول على قائمة مرتبطة ، في المتوسط ​​، ستستغرق مجموعة العمليات هذه حوالي 500000 مرة أطول من تلك الموجودة في المصفوفة. يمكن أن يكون هذا الفرق بين 1 ميكروثانية و 5 ثوانٍ ، أو ثانية واحدة و ... 6 أيام. حتى بالنسبة للبرامج الصغيرة ، يمكن أن يعني الفرق بين غير ملحوظ وملحوظ.

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