سؤال

لماذا لا تستخدم اللغة تقييم ماس كهربائى؟هل هناك فوائد لعدم استخدامه؟

أرى أن ذلك قد يؤدي إلى بعض المشاكل في الأداء.هل هذا صحيح؟لماذا؟


سؤال ذو صلة : فوائد استخدام تقييم ماس كهربائى

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

المحلول

أسباب عدم استخدام تقييم ماس كهربائى:

  1. لأنها سوف تتصرف بشكل مختلف وتنتج نتائج مختلفة إذا كانت وظائفك أو الخاصية Gets أو طرق التشغيل لها آثار جانبية.وهذا قد يتعارض مع:أ) معايير اللغة، ب) الإصدارات السابقة من لغتك، أو ج) الافتراضات الافتراضية لمستخدمي لغاتك النموذجيين.هذه هي الأسباب التي تجعل VB لا يعاني من قصر الدائرة الكهربية.

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

أفترض هنا أنك تسأل عن "قصر الدائرة التلقائية والضمنية الخاصة بالترتيب"، وهو ما يتوقعه معظم المطورين من C وC++ وC# وJava وما إلى ذلك.لدى كل من VB وSQL طرق لتوضيح ذلك قوة ماس كهربائى خاص بالطلب.ومع ذلك، عندما يسأل الناس هذا السؤال عادةً، يكون سؤال "افعل ما أقصده"؛أي أنهم يقصدون "لماذا لا يفعل ما أريد؟"، كما هو الحال في الدائرة القصيرة تلقائيًا بالترتيب الذي كتبته به.

نصائح أخرى

واحد يستفيد أستطيع أن أفكر في أن بعض العمليات قد يكون من الآثار الجانبية التي قد تتوقع أن يحدث.

مثال:

if (true || someBooleanFunctionWithSideEffect()) {
    ...
}

ولكن هذا عادة هو مكروه.

وادا لا تفعل ذلك بشكل افتراضي. من أجل إجبار تقييم ماس كهربائى، لديك لاستخدام and then أو or else بدلا من and أو or.

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

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

في حال كنت مهتما في أي لغة الفعلية المصممين لديك لتقوله حول هذا الموضوع، وهنا مقتطفات من في آدا 83 (اللغة الأصلية) الأساس المنطقي :

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

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

     

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

     

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

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

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

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

تتضمن دائرة القصر في الواقع تفرع الكود، لذا قد تكون عمليات الدائرة القصيرة ضارة على بنيات SIMT مثل CUDA.

- ولكن كما قال بيل، هذا أحد الاعتبارات المتعلقة بالأجهزة.بقدر ما أو إلى هذا الحد اللغات اذهب، سأجيب على سؤالك بصوت مدوٍ لا:منع ماس كهربائى يفعل لا منطقي.

أود أن أقول 99 مرة من أصل 100 إنني أفضل مشغلي الدائرة القصيرة للأداء.

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

1.) عندما تريد استدعاء وظيفتين أو أكثر في عبارة if بغض النظر عن القيمة التي يتم إرجاعها بواسطة الأولى.

if (isABC() || isXYZ()) // short-circuiting logical operator
    //do stuff;

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

لذلك بدلا من ذلك يمكنك القيام بذلك:

if (isABC() | isXYZ()) // non-short-circuiting bitwise operator
    //do stuff;

2.) عندما تقوم بإجراء عمليات حسابية منطقية باستخدام الأعداد الصحيحة.

myNumber = i && 8; // short-circuiting logical operator

ليس بالضرورة نفس:

myNumber = i & 8; // non-short-circuiting bitwise operator

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

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

إذا أردت الجهة اليمنى ليتم تقييمها:

if( x < 13 | ++y > 10 )
    printf("do something\n");

وربما أردت ذ ليمكن زيادة أم لا س <13. حجة جيدة ضد القيام بذلك، ومع ذلك، هو أن تهيئة الظروف من دون آثار جانبية غير عادة أفضل الممارسات البرمجة.

ونتيجة لامتداد:

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

ادا لغة برمجة تدعم كل من العوامل المنطقية التي لم ماس كهربائى (AND، OR)، ل يسمح مترجم لتحسين وربما تتم بشكل مواز يبني، ومشغلي مع طلب صريح لدائرة كهربائية قصيرة (AND THEN، OR ELSE) عند هذا ما رغبات مبرمج. الجانب السلبي لهذا النهج المزدوج محاور هو جعل اللغة قليلا أكثر تعقيدا. (1000 قرارات التصميم التي اتخذت في نفسه "دعونا نفعل على حد سواء!" سوف الوريد جعل لغة البرمجة على الكثير أكثر تعقيدا عموما؛ -)

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

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

ومهلا، انها قليلا من امتداد ولكن هل سألت "لماذا لغة" ... وليس "لماذا لغة".

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

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

في اللمعان، وكتابة ما يعادل

وif (y <> 0) then 100/y else 100

وهو خطأ المبتدئين نموذجي. في القسمة على صفر لا يتم تجنبها، لأنه يتم تقييم التعبير 100 / ص حتى على دورات عندما ص = 0.

ولأن قصر في الدائرة الكهربائية يمكن تغيير سلوك تطبيق IE:

if(!SomeMethodThatChangesState() || !SomeOtherMethodThatChangesState())

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

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

وكمثال على ذلك، ويقول يأتي معيل عبر هذه السطور:

if(user.inDatabase() || user.insertInDatabase()) 
    user.DoCoolStuff();

ويستغرق بضع ثوان لندرك أن القصد من ذلك هو "إذا كان المستخدم غير موجود في قاعدة البيانات، تضاف له / لها / له؛ إذا كان هذا يعمل تفعل الاشياء باردة".

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

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

توجد بالفعل ردود رائعة حول مشكلة الآثار الجانبية، لكنني لم أر أي شيء فيما يتعلق بجانب الأداء في السؤال.

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

  • الكود موجود في حلقة داخلية يتم استدعاؤها بشكل متكرر
  • هناك تكلفة عالية مرتبطة بتقييم التعبيرات (ربما IO أو عملية حسابية باهظة الثمن)

والتقييم دائرة قصر يوفر تلقائيا تقييم المشروط عن جزء من التعبير.

والميزة الرئيسية هي أنه يبسط التعبير.

ويمكن تحسين الأداء ولكن هل يمكن أن نلاحظ أيضا ركلة جزاء لعبارات بسيطة جدا.

ونتيجة أخرى هي أن الآثار الجانبية لتقييم التعبير يمكن أن تتأثر.

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

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

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

وقد تحدث

والعديد من الإجابات حول الآثار الجانبية. وهنا مثال بيثون دون آثار جانبية التي (في رأيي) تقصير الدائرة يحسن القراءة.

for i in range(len(myarray)):
  if myarray[i]>5 or (i>0 and myarray[i-1]>5):
    print "At index",i,"either arr[i] or arr[i-1] is big"

وودائرة قصر يضمن نحن لا محاولة الوصول myarray [-1]، والذي من شأنه أن يرفع استثناء منذ صفائف بيثون تبدأ في 0. يمكن بالطبع أن كتابة التعليمات البرمجية بدون قصيرة الدوائر، ومنها مثلا.

for i in range(len(myarray)):
  if myarray[i]<=5: continue
  if i==0: continue
  if myarray[i-1]<=5: continue
  print "At index",i,...

ولكن أعتقد إصدار ماس كهربائى هو أكثر قابلية للقراءة.

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