performance - استراتيجيات تحسين الأداء في الملاذ الأخير




optimization language-agnostic (20)

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

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

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

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

لنفرض:

  • الرمز بالفعل يعمل بشكل صحيح
  • الخوارزميات المختارة هي بالفعل مثالية لظروف المشكلة
  • تم قياس الشفرة ، وتم عزل الروتين المسيء
  • سيتم أيضًا قياس جميع محاولات تحسينها لضمان أنها لا تزيد الأمور سوءًا

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

من الناحية المثالية ، حاول أن تجعل الإجابات حيادية اللغة ، وأن تشير إلى أي اتجاهات جانبية للإستراتيجيات المقترحة عند الاقتضاء.

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


أقضي معظم حياتي في هذا المكان. السكتات الدماغية واسعة هي لتشغيل البروفايل الخاص بك والحصول عليها لتسجيل:

  • ذاكرة التخزين المؤقت يفتقد . ذاكرة التخزين المؤقت للبيانات هي المصدر رقم 1 للأكشاك في معظم البرامج. تحسين معدل ضرب ذاكرة التخزين المؤقت عن طريق إعادة تنظيم هياكل البيانات المسيئة للحصول على موقع أفضل ؛ هياكل حزمة وأنواع رقمية لأسفل للقضاء على بايت مهدرة (وبالتالي جلب مخبأ إهدار) ؛ جلب البيانات كلما كان ذلك ممكنا للحد من الأكشاك.
  • تحميل الحماله المخازن . يمكن أن تؤدي فرضيات المجمِّع حول التعرُّف على المؤشر ، والحالات التي يتم نقل البيانات فيها بين مجموعات التسجيل غير المتصلة عبر الذاكرة ، إلى حدوث سلوك مرضي معين يؤدي إلى مسح خط أنابيب وحدة المعالجة المركزية بالكامل على مرجع تحميل. ابحث عن الأماكن التي يتم فيها نقل الطوافات والناقلات والأوتاد لبعضها البعض والقضاء عليها. استخدام __restrict المحول البرمجي حول التعرج.
  • عمليات متناهية الصغر . معظم المعالجات لديها بعض العمليات التي لا يمكن أن تكون pipelined ، ولكن بدلاً من ذلك تشغيل روتين فرعي صغير مخزنة في ROM. الأمثلة على PowerPC هي مضاعفة العدد ، القسمة ، والمبدل بالتحول. المشكلة هي أن خط الأنابيب بأكمله يتوقف عن الموتى أثناء تنفيذ هذه العملية. حاول التخلص من استخدام هذه العمليات أو على الأقل تقسيمها إلى العمليات المخططة المكونة لها حتى تتمكن من الحصول على فائدة الإرسال المنتشر على أي شيء يقوم به باقي البرنامج.
  • سوء الفهم فرع . هذه فارغة للغاية خط الأنابيب. ابحث عن الحالات التي تقضي فيها وحدة المعالجة المركزية وقتًا طويلاً في إعادة تعبئة الأنبوب بعد أحد الفروع ، واستخدم تلميح الفروع إذا كان متاحًا للحصول عليه للتنبؤ بشكل صحيح أكثر. أو الأفضل من ذلك ، استبدل الفروع بحركات مشروطة حيثما أمكن ، خاصة بعد عمليات النقطة العائمة لأن الأنابيب الخاصة بها تكون أعمق عادة وقراءة أعلام الشرط بعد أن تتسبب fcmp في الكشك.
  • نقطة عائمة متتالية . اجعل هذه SIMD.

وهناك شيء آخر أحب القيام به:

  • قم بتعيين المحول البرمجي الخاص بك لإخراج قوائم التجميع وإلقاء نظرة على ما تنبعث منه لوظائف نقطة الاتصال في التعليمة البرمجية الخاصة بك. كل تلك التحسينات الذكية التي "يمكن أن يكون لها مترجم جيد للقيام به تلقائيا"؟ هي احتمالات المترجم الفعلي الخاص بك لا تفعل لهم. رأيت دول مجلس التعاون الخليجي تنبعث منها رمز WTF حقا.

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

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

وهناك الكثير من التعليقات بالفعل ذكر رمز ودية مخبأ. هناك على الأقل اثنين من النكهات المميزة لهذا:

  • تجنب استحضار إحضار الذاكرة.
  • انخفاض ضغط ناقل الذاكرة (عرض النطاق الترددي).

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

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

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


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

  • ... إذا كانت الذاكرة - العثور على واحدة من الكتب التي كتبتها Knuth منذ وقت طويل ، واحدة من سلسلة "فن برمجة الكمبيوتر". على الأرجح هو واحد عن الفرز والبحث - إذا كانت ذاكرتي خاطئة فعليك أن تتعرف على كيفية التعامل مع تخزين بيانات الشريط البطيء. تحويل زوج الذاكرة / الشريط الخاص به عقليا إلى زوج ذاكرة التخزين المؤقت / الذاكرة الرئيسية (أو في زوج ذاكرة التخزين المؤقت L1 / L2) على التوالي. ادرس جميع الحيل التي يصفها - إذا لم تجد شيئًا يحل مشكلتك ، فقم بتوظيف خبير كمبيوتر محترف لإجراء بحث مهني. إذا كانت مشكلة الذاكرة الخاصة بك عن طريق الصدفة مع FFT (ذاكرة التخزين المؤقت تفوت في الفهارس التي عكسها عند إجراء الفراشات 2) ، فلا تستأجر عالماً - بدلاً من ذلك ، يتم إجراء تحسين يدوي للواحد تلو الآخر إلى أن تفوز أو تحصل على الى طريق مسدود. لقد ذكرت بالضغط على آخر بضعة في المئة صحيح؟ إذا كان عدد قليل من المرجح أنك ستفوز.

  • ... إذا كان معالجًا ، فانتقل إلى لغة التجميع. دراسة مواصفات المعالج - ما يأخذ القراد ، VLIW ، SIMD. المكالمات الدالة هي على الأرجح استبدال أكلة القراد. تعلم التحولات حلقة - خط أنابيب ، unroll. قد تكون عمليات التكاثر والأقسام قابلة للاستبدال / interpolated مع تحولات البتات (يمكن أن تتضاعف الضرب بواسطة الأعداد الصحيحة الصغيرة مع الإضافات). جرّب الحيل باستخدام بيانات أقصر - إذا كنت محظوظًا ، فقد تتحول إحدى التعليمات التي تحتوي على 64 بتًا إلى تبديل مع اثنين على 32 أو حتى 4 في 16 أو 8 على 8 بتات. جرب أيضًا بيانات أطول - على سبيل المثال ، قد تتحول الحسابات العائمة لديك أبطأ من العمليات المزدوجة في معالج معين. إذا كان لديك أشياء مثلثية ، قم بمحاربتها باستخدام الجداول المحسوبة مسبقًا ؛ ضع في اعتبارك أيضًا أنه يمكن استبدال شرط القيمة الصغيرة بهذه القيمة إذا كان فقد الدقة ضمن الحدود المسموح بها.

  • ... إذا كانت الشبكة - فكر في ضغط البيانات التي تمر عليها. استبدال نقل XML مع ثنائي. بروتوكولات الدراسة. جرّب UDP بدلاً من TCP إذا تمكنت بطريقة ما من معالجة فقدان البيانات.

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

HTH :)


رمي المزيد من الأجهزة في ذلك!


على الرغم من أني أحب إجابة مايك دونلافي ، إلا أنه في الحقيقة إجابة رائعة في الواقع مع مثال داعم ، أعتقد أنه يمكن التعبير عنه ببساطة شديدة:

تعرف على ما يستغرقه أكبر قدر من الوقت أولاً ، وفهم السبب.

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

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

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

HPH ، asoudmove.


مزيد من الاقتراحات:

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

  • تحريك الإدخال / الإخراج للأمام : قم بتحميل كافة البيانات التي ستحتاجها لإجراء عملية حسابية مسبقًا ، بحيث لا يكون لديك I / O تكرارًا في صميم خوارزمية هامة (وربما كنتيجة مكررة) يسعى القرص ، عند تحميل جميع البيانات في ضربة واحدة قد تجنب البحث).

  • تأخير الإدخال / الإخراج : لا تكتب النتائج حتى تنتهي العملية الحسابية ، وقم بتخزينها في بنية بيانات ثم تفريغها دفعة واحدة في النهاية عند الانتهاء من العمل الشاق.

  • I / O مترابطة : بالنسبة لأولئك الجريئين بما فيه الكفاية ، قم بدمج "I / O في المقدمة" أو "تأخير I / O" مع الحساب الفعلي عن طريق نقل التحميل إلى خيط متوازي ، حتى عندما تقوم بتحميل المزيد من البيانات ، يمكنك العمل في حساب على البيانات التي لديك بالفعل ، أو أثناء حساب الدفعة التالية من البيانات ، يمكنك كتابة النتائج من الدفعة الأخيرة في نفس الوقت.


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

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

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


Did you know that a CAT6 cable is capable of 10x better shielding off extrenal inteferences than a default Cat5e UTP cable?

For any non-offline projects, while having best software and best hardware, if your throughoutput is weak, then that thin line is going to squeeze data and give you delays, albeit in milliseconds... but if you are talking about the last drops, that's a some drops gained, 24/7 for any packge sent or received.


Reduce variable sizes (in embedded systems)

If your variable size is larger than the word size on a specific architecture, it can have a significant effect on both code size and speed. For example, if you have a 16 bit system, and use a long int variable very often, and later realize that it can never get outside the range (−32.768 ... 32.767) consider reducing it to short int.

From my personal experience, if a program is ready or almost ready, but we realize it takes up about 110% or 120% of the target hardware's program memory, a quick normalization of variables usually solves the problem more often than not.

By this time, optimizing the algorithms or parts of the code itself can become frustratingly futile:

  • reorganize the whole structure and the program no longer works as intended, or at least you introduce a lot of bugs.
  • do some clever tricks: usually you spend a lot of time optimizing something, and discover no or very small decrease in code size, as the compiler would have optimized it anyway.

Many people make the mistake of having variables which exactly store the numerical value of a unit they use the variable for: for example, their variable time stores the exact number of milliseconds, even if only time steps of say 50 ms are relevant. Maybe if your variable represented 50 ms for each increment of one, you would be able to fit into a variable smaller or equal to the word size. On an 8 bit system, for example, even a simple addition of two 32-bit variables generates a fair amount of code, especially if you are low on registers, while 8 bit additions are both small and fast.


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

Sometimes the cache will not gain you much, but it's an easy method to just add caching all over and then disable it where it doesn't help. I've often found this to gain huge performance without having to micro-analyse the code.


فرق تسد

إذا كانت مجموعة البيانات التي تتم معالجتها كبيرة جدًا ، فقم بتكرارها فوق أجزاء منها. إذا كنت قد انتهيت من تنفيذ التعليمات البرمجية ، فيجب أن يكون التنفيذ سهلاً. إذا كان لديك برنامج مترابط ، فأنت الآن على علم أفضل.


I've spent some time working on optimising client/server business systems operating over low-bandwidth and long-latency networks (eg satellite, remote, offshore), and been able to achieve some dramatic performance improvements with a fairly repeatable process.

  • Measure : Start by understanding the network's underlying capacity and topology. Talking to the relevant networking people in the business, and make use of basic tools such as ping and traceroute to establish (at a minimum) the network latency from each client location, during typical operational periods. Next, take accurate time measurements of specific end user functions that display the problematic symptoms. Record all of these measurements, along with their locations, dates and times. Consider building end-user "network performance testing" functionality into your client application, allowing your power users to participate in the process of improvement; empowering them like this can have a huge psychological impact when you're dealing with users frustrated by a poorly performing system.

  • Analyze : Using any and all logging methods available to establish exactly what data is being transmitted and received during the execution of the affected operations. Ideally, your application can capture data transmitted and received by both the client and the server. If these include timestamps as well, even better. If sufficient logging isn't available (eg closed system, or inability to deploy modifications into a production environment), use a network sniffer and make sure you really understand what's going on at the network level.

  • Cache : Look for cases where static or infrequently changed data is being transmitted repetitively and consider an appropriate caching strategy. Typical examples include "pick list" values or other "reference entities", which can be surprisingly large in some business applications. In many cases, users can accept that they must restart or refresh the application to update infrequently updated data, especially if it can shave significant time from the display of commonly used user interface elements. Make sure you understand the real behaviour of the caching elements already deployed - many common caching methods (eg HTTP ETag) still require a network round-trip to ensure consistency, and where network latency is expensive, you may be able to avoid it altogether with a different caching approach.

  • Parallelise : Look for sequential transactions that don't logically need to be issued strictly sequentially, and rework the system to issue them in parallel. I dealt with one case where an end-to-end request had an inherent network delay of ~2s, which was not a problem for a single transaction, but when 6 sequential 2s round trips were required before the user regained control of the client application, it became a huge source of frustration. Discovering that these transactions were in fact independent allowed them to be executed in parallel, reducing the end-user delay to very close to the cost of a single round trip.

  • Combine : Where sequential requests must be executed sequentially, look for opportunities to combine them into a single more comprehensive request. Typical examples include creation of new entities, followed by requests to relate those entities to other existing entities.

  • Compress : Look for opportunities to leverage compression of the payload, either by replacing a textual form with a binary one, or using actual compression technology. Many modern (ie within a decade) technology stacks support this almost transparently, so make sure it's configured. I have often been surprised by the significant impact of compression where it seemed clear that the problem was fundamentally latency rather than bandwidth, discovering after the fact that it allowed the transaction to fit within a single packet or otherwise avoid packet loss and therefore have an outsize impact on performance.

  • Repeat : Go back to the beginning and re-measure your operations (at the same locations and times) with the improvements in place, record and report your results. As with all optimisation, some problems may have been solved exposing others that now dominate.

In the steps above, I focus on the application related optimisation process, but of course you must ensure the underlying network itself is configured in the most efficient manner to support your application too. Engage the networking specialists in the business and determine if they're able to apply capacity improvements, QoS, network compression, or other techniques to address the problem. Usually, they will not understand your application's needs, so it's important that you're equipped (after the Analyse step) to discuss it with them, and also to make the business case for any costs you're going to be asking them to incur. I've encountered cases where erroneous network configuration caused the applications data to be transmitted over a slow satellite link rather than an overland link, simply because it was using a TCP port that was not "well known" by the networking specialists; obviously rectifying a problem like this can have a dramatic impact on performance, with no software code or configuration changes necessary at all.


If better hardware is an option then definitely go for that. Otherwise

  • Check you are using the best compiler and linker options.
  • If hotspot routine in different library to frequent caller, consider moving or cloning it to the callers module. Eliminates some of the call overhead and may improve cache hits (cf how AIX links strcpy() statically into separately linked shared objects). This could of course decrease cache hits also, which is why one measure.
  • See if there is any possibility of using a specialized version of the hotspot routine. Downside is more than one version to maintain.
  • Look at the assembler. If you think it could be better, consider why the compiler did not figure this out, and how you could help the compiler.
  • Consider: are you really using the best algorithm? Is it the best algorithm for your input size?

Last few % is a very CPU and application dependent thing....

  • cache architectures differ, some chips have on-chip RAM you can map directly, ARM's (sometimes) have a vector unit, SH4's a useful matrix opcode. Is there a GPU - maybe a shader is the way to go. TMS320 's are very sensitive to branches within loops (so separate loops and move conditions outside if possible).

The list goes on.... But these sorts of things really are the last resort...

Build for x86, and run Valgrind /Cachegrind against the code for proper performance profiling. Or Texas Instruments' CCStudio has a sweet profiler. Then you'll really know where to focus...


Not nearly as in depth or complex as previous answers, but here goes: (these are more beginner/intermediate level)

  • obvious: dry
  • run loops backwards so you're always comparing to 0 rather than a variable
  • use bitwise operators whenever you can
  • break repetitive code into modules/functions
  • cache objects
  • local variables have slight performance advantage
  • limit string manipulation as much as possible

The google way is one option "Cache it.. Whenever possible don't touch the disk"


Very difficult to give a generic answer to this question. It really depends on your problem domain and technical implementation. A general technique that is fairly language neutral: Identify code hotspots that cannot be eliminated, and hand-optimize assembler code.


  • إجراءات مضمنة (القضاء على الاتصال / الإرجاع ودفع المعلمة)
  • حاول التخلص من الاختبارات / المحولات باستخدام عمليات البحث عن الجدول (إذا كانت أسرع)
  • الحلقات غير الممغنطة (جهاز Duff) إلى النقطة التي تناسبها فقط في ذاكرة التخزين المؤقت لوحدة المعالجة المركزية (CPU)
  • توطين الوصول إلى الذاكرة حتى لا تفجير ذاكرة التخزين المؤقت
  • ترجمة الحسابات ذات الصلة إذا لم يكن المحسن يقوم بذلك بالفعل
  • إزالة الثغرات حلقة إذا لم يكن المحسن القيام بذلك بالفعل

  • عندما تصل إلى النقطة التي تستخدم فيها الخوارزميات الفعالة ، عليك سؤال ما تحتاج إليه من سرعة أو ذاكرة أكبر . استخدم التخزين المؤقت "للدفع" في الذاكرة لمزيد من السرعة أو استخدام العمليات الحسابية لتقليل أثر الذاكرة.
  • إذا كان ذلك ممكنا (وأكثر فعالية من حيث التكلفة) رمي الأجهزة على المشكلة - وحدة المعالجة المركزية أسرع ، ذاكرة أكبر أو HD يمكن حل المشكلة بشكل أسرع ثم محاولة التعليمة البرمجية.
  • استخدم التوازي إذا أمكن - شغّل جزءًا من الشفرة على عدة سلاسل.
  • استخدم الأداة المناسبة لهذه المهمة . تعمل بعض لغات البرمجة على إنشاء شفرة أكثر كفاءة ، حيث يؤدي استخدام الكود المُدار (أي Java / .NET) إلى تسريع عملية التطوير ولكن لغات البرمجة الأصلية تقوم بإنشاء كود تشغيل أسرع.
  • مايكرو الأمثل . كانت قابلة للتطبيق فقط يمكنك استخدام التجميع الأمثل لتسريع أجزاء صغيرة من التعليمات البرمجية ، باستخدام تحسينات SSE / vector في الأماكن الصحيحة يمكن زيادة الأداء بشكل كبير.




language-agnostic