من خلال عقلي الإنساني ، كنت أفكر دائمًا بهذه الطريقة - إذا كان المبرمج يعرف كيفية جعله أكثر أداءً ، فمن الضروري أن يجعله أكثر أداءً. حل منتج = الحل الصحيح. قد تكون إحدى لغات البرمجة أبطأ من لغة أخرى ، وإذا اتضح أن لغة البرمجة تضيع.
حسنًا ، بالتأكيد - إذا كان المطور متخصصًا في الأداء ، فسوف يغرق في كل هذه الأشياء ، حتى لو كانت مخطئة.
بطبيعة الحال ، كل هذا هراء ، لكن ليس لي أن أخبركم به. لذلك ، أندريه أكينشين ، مطور وعالم رياضيات ، مرشح للعلوم الفيزيائية والرياضية ، مشرف BenchmarkDotNet و perfolizer ، مؤلف كتاب Pro .NET Benchmarking ومهندس رائع جدًا ، جاء إلى البودكاست الخاص بنا.
فيما يلي اقتباسات مختارة.
من المستحيل توقع كل شيء في المعايير
زميل لي مؤخرا لديه ما يلي. كان يبرمج في الصباح ، كل شيء كان على ما يرام معه ، كل شيء يعمل بسرعة. في مرحلة ما ، بدأ كل شيء في التمسك - رايدر بطيء ، IDEA ، المتصفح - كل شيء بطيء. لم يستطع أن يفهم بأي شكل كان الأمر؟ ثم أدركت. كان يعمل على جهاز كمبيوتر محمول أسود كان يقف بجانب النافذة. كان الجو باردًا جدًا في الصباح ، وشرقت الشمس خلال النهار ، وأصبح الكمبيوتر المحمول ساخنًا جدًا ودخل في الاختناق الحراري.
إنه يعلم أن هناك شيئًا من هذا القبيل ، ويعرف أن البيئة المادية يمكن أن تؤثر على الأداء ، وسرعان ما أدرك ما كان يحدث. كان لديه نموذج في رأسه يعمل وفقًا له العالم ، وضمن هذا النموذج ، اكتشف بسرعة ما كان يجري.
وهذا يعني أن أهم مهارة يمكن الحصول عليها في قياس الأداء هي عدم معرفة كل شيء بكل التفاصيل - كل أوقات التشغيل وجميع الأجهزة. الشيء الرئيسي هو فهم كيف يجب أن تتصرف من أجل إيجاد المشكلة ، ويفضل أن يكون ذلك في أسرع وقت ممكن وبأقل جهد ممكن.
سأعطي تشبيهًا باللغات. عندما تتعلم لغة البرمجة الوظيفية الأولى الخاصة بك ، فأنت بحاجة إلى تعديل طفيف في موقفك من العالم - لفهم مبادئ البرمجة الوظيفية ، كيف تحتاج إلى التفكير بشكل عام. ثم تأخذ اللغة الوظيفية التالية X ، ولديك بالفعل هذه المبادئ في رأسك. تشاهد زوجين مرحبًا بالعالم وتبدأ في الكتابة أيضًا.
في الوقت نفسه ، قد لا تعرف بعض الفروق الدقيقة في اللغة. قد لا تعرف كيف تعمل بعض التركيبات النحوية ، لكن هذا لا يزعجك كثيرًا. تشعر بالراحة وتكتب. واجهت سلوكًا غير مفهوم - قرأت الدليل ، وفهمته ، وحقيقة جديدة دخلت بسهولة في صورتك للعالم ، وذهبت إلى أبعد من ذلك. ولن تتعلم أبدًا جميع الفروق الدقيقة لجميع اللغات الوظيفية في العالم ، لكن النهج العام سيبقى في رأسك.
أعتقد أنك بحاجة إلى الوصول إلى مستوى مماثل في كل منطقة ، ثم المضي قدمًا.
في مرحلة ما من القياس ، ركزت بشكل خاص على دقة القياس ، على ميزات أوقات تشغيل معينة ، قطعة من الحديد ، شيء آخر. ثم توقفت عن اكتشاف أمريكا في كل مرة ، وبدأت جميع مشكلات الأداء تقع ضمن الفئات التي أعرفها بالفعل. وذهبت في اتساع - في اتجاه تحليل الأداء: ماذا أفعل بالأرقام التي قمنا بقياسها. وهذا هو المجال الذي لم أصل فيه بعد إلى حافة المعرفة. لقد أصبحت بعض الأشياء واضحة بالنسبة لي بالفعل ، ولكن لا يزال هناك الكثير من العمل في المستقبل - لفهم كيفية تطبيق كل هذا في الممارسة العملية ، والصيغ التي يجب استخدامها ، والتي لا يجب استخدامها ، وما هي الأساليب الجيدة ، والتي ليست كذلك.
المقارنة المعيارية من أجل المقارنة المعيارية ليست أفضل شيء يمكن القيام به
يجب أن يكون هناك دائمًا بعض متطلبات أداء العمل ، يجب أن تفهم دائمًا ما تسعى إليه. إذا لم يكن لديك متطلبات عمل ، فلا فائدة من أداء الأداء أيضًا. وفقًا لذلك ، عندما تكون هناك متطلبات عمل ، فأنت تبدأ بالفعل في فهم الأساليب التي يمكنك استخدامها وأيها لا يمكنك ، على الأقل بالعين. إذا لم يكن الأمر كذلك ، فقم بإجراء القياس والتحقق - أي الأساليب تتناسب مع متطلباتك.
وعندما يكون لديك مجموعة من الخوارزميات ، وخيارات لكتابة الكود والتصميم وأشياء أخرى ، وكل شيء يتناسب مع المتطلبات - فأنت تختار بالفعل ما سيكون أكثر اتساقًا مع بقية المشروع ، والذي يعكس وجهات نظرك حول الجماليات ، حول كيفية كتابة التعليمات البرمجية بشكل صحيح ...
بشكل تقريبي ، إذا كان لدي 10 عناصر كحد أقصى في المجموعة ، وكان هناك خياران - اكتب خوارزمية بسيطة لمكعب أو واحد معقد جدًا لـ n * log n - سأكتب واحدة بسيطة لمكعب سيكون واضحًا للجميع ، والذي سيكون من السهل صيانته وتعديله. لأنني أفهم أنه لن يخترق أبدًا قيود الأداء الخاصة بي.
إذا كتبت حلاً بطيئًا لمجموعة بيانات صغيرة ، ثم استخدمته لمجموعة بيانات كبيرة ، ولم يكن له عواقب وخيمة (عادةً لا) - حسنًا ، دعنا نذهب ونصلحه. ولكن سيكون هناك في الرأس نموذج لكيفية تجنب هذه الأخطاء في المستقبل.
على سبيل المثال ، يمكنك وضع تأكيد في بداية الطريقة بحيث لا يتجاوز عدد العناصر في المجموعة رقم كذا وكذا. بعد ذلك ، سيرى المبرمج التالي الذي يحاول عن طريق الخطأ استخدام طريقتك استثناءً على الفور ولن يستخدمه. مثل هذه الأشياء تأتي مع الخبرة.
هناك مشكلة أخرى - متطلبات العمل المتقلبة. سوف يتغيرون بالتأكيد - هذه بديهية لواقعنا ، لا توجد طريقة للابتعاد عن هذا. من خلال الخبرة ، سوف تكون قادرًا على التنبؤ بالعين حيث قد تتغير المتطلبات ، حيث يستحق وضع مستوى جيد من الأداء ، حيث قد يزيد الحمل.
في حين أن هذا الحدس غير موجود ، يمكنك الخضوع للتجربة والخطأ ومعرفة ما سيحدث.
لديك دائمًا مفاضلة بين الأداء والجمال
إذا كنت تكتب بأكبر قدر ممكن من الكفاءة ، فعلى الأرجح ، ستكون شفرتك فظيعة ومثيرة للاشمئزاز - وحتى إذا أغمضت عينيك عن الجماليات ، فسيكون من الصعب صيانتها ، وستظهر أخطاء خفية فيها باستمرار ، لأن البنية سيئة ، والرمز سيئ ، وكل شيء سيء.
أعتقد أنك بحاجة إلى التركيز على متطلبات العمل الحالية ، وكتابة أنظف ، وفهم ، وجمال ، وقابل للصيانة داخلها. وفي اللحظة التي يبدأ فيها الجني (أو هناك شعور بأنه سيبدأ قريبًا) ، فإن شيئًا ما يتغير بالفعل.
وحتى إذا كنت تركز دائمًا على الأداء فقط ، فلا يوجد شيء اسمه كود مُحسَّن بشكل مثالي وأقصى قدر من الإنتاجية. هذا يعني كل شيء - نسوا C # ، نسوا كل اللغات الجميلة. ومن الأفضل أن تكتب بشكل عام في أكواد الآلة ، لأن المجمع محدود أيضًا في بناء الجملة. وإذا كتبت على الفور بالبايت ، فستحصل على أداء أفضل.
في بعض الحالات ، يكون الرمز الأسرع هو الأجمل والأكثر وضوحًا والأكثر صحة. لكن مثل هذه المقايضات تنشأ حتماً في عشرات ومئات اللحظات الصغيرة. لنفترض أن هناك شيئًا مثل التحقق من انتهاك حدود المصفوفة. يمكنك الموافقة على أن وقت التشغيل سيهتم بك للتحقق من حدود المصفوفة في جميع الأماكن ، وإذا انتقلت إلى العنصر الأول ناقص ، فستحصل على استثناء ولن تقرأ من الجزء الأيسر من الذاكرة.
ومن أجل هذه الثقة بأنك بالتأكيد لا تطرح أبدًا من الجزء الخطأ من الذاكرة - فأنت تدفع مقابل جزء صغير من الأداء. أي أننا نستخدم الأداء كمورد من أجل جعل البرنامج أكثر استقرارًا وفهمًا وقابلية للصيانة.
اللغة ليس لها خاصية مثل الأداء
إذا رأيت مقالة تشير إلى أن X أسرع من Y ، فيمكنك إغلاق المقالة. اللغة هي تجريد رياضي. هذه مجموعة من القواعد التي يتم تجميع البرنامج وفقًا لها. ليس له أداء ، ليس له أداء ، إنه شيء موجود في رأسك ويتجسد في محرر نصوص.
يتوفر الأداء لأوقات تشغيل وبيئات وبرامج محددة وقرصنة محددة. عندما تأخذ كل هذه العوامل في الاعتبار ، يمكنك التحدث عن الأداء. ولكن هناك انفجار اندماجي ، ولا يمكنك القول أن رمزًا واحدًا في هذه اللغة يكون دائمًا أسرع من رمز آخر في هذه اللغة ، لأن الإصدارات الجديدة من الأجهزة وأوقات التشغيل تظهر. لن تمر أبدًا بجميع المجموعات الممكنة من العوامل الخارجية في حياتك. apishkas الذي تستخدمه يختلف اختلافًا جوهريًا.
على سبيل المثال ، في لغة شرطية في المراحل الأولى من التطور ، قاموا بتطبيق طريقة للفرز باستخدام الفقاعة. حسنًا ، لا أعرف - أراد الرجال طرح الإصدار في أسرع وقت ممكن ، وكتبوا أبسط ترتيب يمكنهم القيام به. لقد أخذتها ، واستخدمت هذه الطريقة ، واتضح أنها أبطأ في البيانات الضخمة منها في لغة أخرى حيث يتم الترتيب السريع. هل هذا يعني أنه يمكنك التحدث عن أداء بعض اللغات؟ لا. يمكنك القول أن هذه القطعة المحددة من هذه اللغة على نظام التشغيل هذا ، على هذا الجهاز ، في هذه البيئات ، تعمل بشكل أبطأ من قرص آخر من لغة أخرى في بيئة أخرى. لذلك يمكنك القول. لكنها ستتحول إلى فقرة طويلة جدًا من النص ليتم صياغتها بشكل صحيح.
تقليديًا ، يمكننا القول أن C ++ أسرع في معظم الحالات من JavaScript. ولكن سيكون من الأصح القول إن مبرمجي C ++ الذين يتمتعون بخبرة جيدة في C ++ والذين يكتبون بلغة C ++ سيكتبون برنامجًا من المحتمل أن يكون أسرع من JavaScript javascriptor سيكتب شيئًا يعمل في المتصفح.
ولكن هناك أيضًا العديد من التحفظات هنا. ولكن ماذا لو قال أحد المتأنق الذي كتب بلغة جافا سكريبت أنه ليس كذلك ، وذهب إلى هناك نوعًا ما من WebAssembly أو أي شيء آخر لإعادة. أو ابحث على GitHub عن مترجم جافا سكريبت فائق مترجم يعمل مع مجموعة فرعية مقتطعة جدًا من JS بواسطة ثلاثة تركيبات بناء ونصف ، ولكنه ينتج رمزًا أصليًا بسرعة فائقة.
وهناك ، إذا كنت ترغب في ذلك ، يمكنك كتابة رمز يتجاوز C ++. علاوة على ذلك ، يمكنك كتابة مترجم JavaScript الخاص بك ، والذي سيتم تصميمه لتجميع برنامج واحد وتجاوز "الإيجابيات" بسرعة. وهذا ، من حيث المبدأ ، خيار صالح.
الضغط الاجتماعي لمشروع مفتوح المصدر شعبي
مع نمو وشعبية المشاريع يأتي مستوى معين من المسؤولية. لكن ليس لديك التزامات حقًا. ليس من السهل دائمًا فهم هذه الحقيقة ، خاصةً عندما يأتي كل أنواع الأشخاص إلى GitHub ويقولون: "إنها لا تعمل معي هنا! إصلاحه بشكل عاجل! أنا حقا بحاجة إلى هذا للعمل. اذهب وأصلحه! " أو يحصل الرجل على وظيفة وأنا في إجازة. مرت ثلاثة أو أربعة أيام ، لم أر حتى أنه بدأ شيئًا هناك. أنا أستريح في مكان ما ، ويبدأ الرجل - "لماذا بحق الجحيم لا تجيبني؟ ما نوع المجتمع الذي يمتلكه هذا المشروع ؟! بشكل عام ، أنتم جميعًا مقرفون ، وعليكم أن تفعلوا أشياء سيئة معك! لقد أهدرت وقتي ، وكتبت لك أنك مخطئ ، وأنت لا تفعل شيئًا به على الإطلاق ، لقد كنت تتجاهلني لمدة أربعة أيام! كيف يعقل ذلك ؟! "
وكلما كان المشروع أكثر شهرة ، زاد الضغط الاجتماعي من الأشخاص الذين يعتقدون أن المصدر المفتوح هو مكان يقوم فيه الآخرون بعملك نيابة عنك مجانًا. لكن في الواقع ليس كذلك.
والآن ، عندما تظهر المناعة ضد الأشخاص الذين يريدون شيئًا منك ، تصبح الحياة أسهل بكثير. أحصل الآن على BenchmarkDorNet عندما يكون لدي الوقت والمزاج للترميز. أعلم أن هناك الكثير من الأخطاء. إنها في الغالب غير نقدية ، وتتعلق ببعض الحالات الهامشية - في بيئة كذا وكذا مع أحدث معاينة لـ DotNet الخامسة ، هناك شيء ما في مكان ما لا يعمل. حسنًا ، حسنًا ، دعها لا تعمل. عندما أكون في حالة مزاجية ، سأذهب وأصلحها.
إذا احتاج الآخرون إليه ، يمكنهم إصلاحه بأنفسهم وإرسال طلب سحب - سأقوم بمراجعة عندما يكون لدي الوقت والمزاج.
شاهد البودكاست بأكمله هنا .