هل تعتقد أن هذين الخيارين للتحقق من الشروط داخل الحلقة متكافئين في الأداء؟
if a > b && c*2 > d { .... }
بدأ كل شيء بـ "عملية الاحماء للدماغ" ، كان من الضروري إعطاء مثال للبحث الأمثل عن مجموعة من الأعداد الصحيحة [-x .... x] من أكبر عدد زوجي. كنت أتساءل كيف سيكون الأداء العالي إذا ، لمعرفة الرقم الزوجي أم لا ، استخدام الضرب المنطقي بمقدار 1.
تجربتي في البرمجة على Go ليست كبيرة جدًا ، ما يزيد قليلاً عن عام ونصف العام ، لقد استخدمتها ، على الرغم من كثير من الأحيان ، ولكن لأغراض نفعية بحتة (جيدًا ، ربما باستثناء مشروع واحد يتعلق بخدمة http محملة للغاية) ، لذلك بدأت به. افتح GoLand واكتب اختبارًا بسيطًا
package main import ( "fmt" "log" "math" "math/rand" "time" ) const size = 100000000
نحصل على نتيجة توضح أنه كلما ارتفعت العتبة ، تظهر التقلبات في كثير من الأحيان من حيث الأداء.
مقارنةmax threshold: 128
maxEvenDividing result: 126 duration 116.0067ms
maxEvenConjunction result: 126 duration 116.0066ms
max threshold: 16384
maxEvenDividing result: 16382 duration 115.0066ms
maxEvenConjunction result: 16382 duration 111.0064ms
......
max threshold: 8388608
maxEvenDividing result: 8388606 duration 109.0063ms
maxEvenConjunction result: 8388606 duration 109.0062ms
max threshold: 16777216
maxEvenDividing result: 16777214 duration 108.0062ms
maxEvenConjunction result: 16777214 duration 109.0062ms
max threshold: 33554432
maxEvenDividing result: 33554430 duration 114.0066ms
maxEvenConjunction result: 33554430 duration 110.0063ms
max threshold: 67108864
maxEvenDividing result: 67108860 duration 111.0064ms
maxEvenConjunction result: 67108860 duration 109.0062ms
max threshold: 134217728
maxEvenDividing result: 134217726 duration 108.0062ms
maxEvenConjunction result: 134217726 duration 109.0063ms
max threshold: 268435456
maxEvenDividing result: 268435446 duration 111.0063ms
maxEvenConjunction result: 268435446 duration 110.0063ms
من الواضح أنه في هذه الحالة ، بالنسبة للعتبات المختلفة التي لدينا مجموعات بيانات اختبار مختلفة ، يتراوح تحميل المعالج (على كمبيوتر i5-2540M المحمول) حوالي 20..30٪ ، الذاكرة التي يشغلها التطبيق الذي يعمل من تحت متوسطات GoLand حوالي 813 ميغابايت - وهذا أيضًا يؤثر على موثوقية النتيجة ، تحتاج إلى تنفيذ الحفاظ على مجموعات الاختبار على القرص وتشغيل جميع الاختبارات لكل عتبة بمعزل عن بعضها البعض.
بالتفكير في كيفية تنفيذ كل هذا بأقل تكلفة ، أقوم تلقائيًا بتصحيح التحقق من الحالة
if value > current && value&1 == 0 { current = value }
في
if value <= current { continue; } if value&1 == 0 { current = value }
أركض الاختبارات مرة أخرى ... وأتوقف عن فهم شيء :)
يبدأ الوقت المستغرق في التنفيذ في الاختلاف بالفعل ليس بنسبة٪ / جزء من النسبة المئوية ، ولكن بنسبة 10..15٪ أضيف بسرعة اختبارين إضافيين:
func maxEvenDividing2(name string, arr []int32) Result { start := time.Now() var current int32 = math.MinInt32 for _, value := range arr { if value <= current { continue } if value%2 == 0 { current = value } } duration := time.Since(start) result := Result{name, duration, current} return result } func maxEvenConjunction2(name string, arr []int32) Result { start := time.Now() var current int32 = math.MinInt32 for _, value := range arr { if value <= current { continue } if value&1 == 0 { current = value } } duration := time.Since(start) result := Result{name, duration, current} return result }
أنا إطلاق والحصول على هذه الصورة:مجموعة الصفيف الأولي: 100000000
الحد الأقصى للعتبة: 128
maxEven تقسيم النتيجة: 126 مدة 116.0066ms
نتيجة maxEvenDividing2: 126 مدة 79.0045ms
نتيجة maxEvenConjunction: 126 مدة 114.0065ms
نتيجة maxEvenConjunction2: 126 مدة 83.0048ms
الحد الأقصى للعتبة: 256
نتيجة maxEvenDividing: 254 مدة 111.0063ms
نتيجة maxEvenDividing2: 254 مدة 77.0044ms
نتيجة maxEvenConjunction: 254 مدة 110.0063ms
نتيجة maxEvenConjunction2: 254 مدة 80.0046ms
الحد الأقصى للعتبة: 512
maxEven تقسيم النتيجة: 510 مدة 114.0066ms
نتيجة maxEvenDividing2: 510 مدة 80.0045 مللي ثانية
نتيجة maxEvenConjunction: 510 مدة 110.0063ms
نتيجة maxEvenConjunction2: 510 مدة 80.0046ms
الحد الأقصى للعتبة: 1024
maxEven تقسيم النتيجة: 1022 مدة 109.0063ms
نتيجة maxEvenDividing2: 1022 مدة 77.0044ms
نتيجة maxEvenConjunction: 1022 مدة 111.0063ms
نتيجة maxEvenConjunction2: 1022 مدة 81.0047ms
الحد الأقصى للعتبة: 2048
maxEven تقسيم النتيجة: 2046 مدة 114.0065ms
نتيجة maxEvenDividing2: 2046 مدة 79.0045ms
نتيجة maxEvenConjunction: 2046 مدة 113.0065ms
نتيجة maxEvenConjunction2: 2046 مدة 81.0046ms
الحد الأقصى للعتبة: 4096
maxEven تقسيم النتيجة: 4094 مدة 114.0065ms
نتيجة maxEvenDividing2: 4094 مدة 80.0046 مللي ثانية
نتيجة maxEvenConjunction: 4094 مدة 111.0063ms
نتيجة maxEvenConjunction2: 4094 مدة 78.0045ms
الحد الأقصى للعتبة: 8192
maxEven تقسيم النتيجة: 8190 مدة 107.0062ms
نتيجة maxEvenDividing2: 8190 مدة 77.0044ms
نتيجة maxEvenConjunction: 8190 مدة 111.0063ms
نتيجة maxEvenConjunction2: مدة 8190 77.0044 مللي ثانية
الحد الأقصى للعتبة: 16384
maxEven تقسيم النتيجة: 16382 مدة 109.0063ms
نتيجة maxEvenDividing2: 16382 مدة 77.0044ms
نتيجة maxEvenConjunction: 16382 مدة 108.0062ms
نتيجة maxEvenConjunction2: المدة 16382 77.0044ms
الحد الأقصى للعتبة: 32768
maxEven تقسيم النتيجة: 32766 مدة 112.0064ms
نتيجة maxEvenDividing2: المدة 32766 77.0044 مللي ثانية
نتيجة maxEvenConjunction: مدة 32766 109.0062ms
نتيجة maxEvenConjunction2: مدة 32766 78.0045ms
الحد الأقصى للعتبة: 65536
maxEven تقسيم النتيجة: 65534 مدة 109.0062ms
نتيجة maxEvenDividing2: مدة 65534 75.0043 مللي ثانية
نتيجة maxEvenConjunction: مدة 65534 109.0063ms
نتيجة maxEvenConjunction2: مدة 65534 79.0045 مللي ثانية
الحد الأقصى للعتبة: 131072
maxEven تقسيم النتيجة: 131070 مدة 108.0061ms
نتيجة maxEvenDividing2: 131070 مدة 76.0044ms
نتيجة maxEvenConjunction: 131070 مدة 110.0063ms
نتيجة maxEvenConjunction2: المدة 131070 80.0046 مللي ثانية
الحد الأقصى للعتبة: 262144
maxEven تقسيم النتيجة: 262142 مدة 110.0063ms
نتيجة maxEvenDividing2: مدة 262142 76.0044 مللي ثانية
نتيجة maxEvenConjunction: 262142 مدة 107.0061ms
نتيجة maxEvenConjunction2: مدة 262142 78.0044ms
الحد الأقصى للعتبة: 524288
maxEven تقسيم النتيجة: 524286 مدة 109.0062ms
نتيجة maxEvenDividing2: 524286 مدة 78.0045ms
نتيجة maxEvenConjunction: 524286 مدة 109.0062ms
نتيجة maxEvenConjunction2: 524286 مدة 80.0046ms
الحد الأقصى للعتبة: 1048576
maxEven تقسيم النتيجة: 1048574 مدة 109.0063ms
نتيجة maxEvenDividing2: 1048574 مدة 80.0045ms
نتيجة maxEvenConjunction: 1048574 مدة 114.0066ms
نتيجة maxEvenConjunction2: 1048574 مدة 78.0044ms
الحد الأقصى للعتبة: 2097152
maxEven تقسيم النتيجة: 2097150 مدة 111.0064ms
نتيجة maxEvenDividing2: 2097150 مدة 79.0045ms
نتيجة maxEvenConjunction: 2097150 مدة 112.0064ms
نتيجة maxEvenConjunction2: 2097150 مدة 77.0044ms
الحد الأقصى للعتبة: 4194304
maxEven تقسيم النتيجة: 4194302 مدة 111.0063 مللي ثانية
نتيجة maxEvenDividing2: 4194302 مدة 78.0045ms
نتيجة maxEvenConjunction: 4194302 مدة 111.0063ms
نتيجة maxEvenConjunction2: 4194302 مدة 77.0044ms
الحد الأقصى للعتبة: 8388608
maxEven تقسيم النتيجة: 8388606 مدة 109.0062ms
نتيجة maxEvenDividing2: 8388606 مدة 78.0045ms
نتيجة maxEvenConjunction: مدة 8388606 114.0065ms
نتيجة maxEvenConjunction2: 8388606 مدة 78.0045ms
الحد الأقصى للعتبة: 16777216
maxEven تقسيم النتيجة: 16777214 مدة 109.0062ms
نتيجة maxEvenDividing2: 16777214 مدة 77.0044ms
نتيجة maxEvenConjunction: 16777214 مدة 109.0063ms
نتيجة maxEvenConjunction2: 16777214 مدة 77.0044ms
الحد الأقصى للعتبة: 33554432
maxEven تقسيم النتيجة: 33554430 مدة 113.0065ms
نتيجة maxEvenDividing2: 33554430 مدة 78.0045ms
نتيجة maxEvenConjunction: 33554430 مدة 110.0063ms
نتيجة maxEvenConjunction2: 33554430 مدة 80.0045ms
الحد الأقصى للعتبة: 67108864
maxEven تقسيم النتيجة: 67108860 مدة 112.0064ms
نتيجة maxEvenDividing2: 67108860 مدة 77.0044ms
نتيجة maxEvenConjunction: 67108860 مدة 112.0064ms
نتيجة maxEvenConjunction2: مدة 67108860 80.0046 مللي ثانية
الحد الأقصى للعتبة: 134217728
maxEven تقسيم النتيجة: 134217726 مدة 109.0063ms
نتيجة maxEvenDividing2: 134217726 مدة 78.0044ms
نتيجة maxEvenConjunction: 134217726 مدة 114.0065ms
نتيجة maxEvenConjunction2: 134217726 مدة 81.0047ms
الحد الأقصى للعتبة: 268435456
maxEven تقسيم النتيجة: 268435446 مدة 111.0064ms
نتيجة maxEvenDividing2: 268435446 مدة 79.0045ms
نتيجة maxEvenConjunction: 268435446 مدة 114.0065ms
نتيجة maxEvenConjunction2: المدة 268435446 79.0045ms
الحد الأقصى للعتبة: 536870912
maxEven تقسيم النتيجة: 536870910 المدة 107.0062 مللي ثانية
نتيجة maxEvenDividing2: المدة 536870910 76.0043 مللي ثانية
نتيجة maxEvenConjunction: 536870910 مدة 109.0062ms
نتيجة maxEvenConjunction2: 536870910 مدة 80.0046ms
شرح واضح عن سبب عدم قيام برنامج التحويل البرمجي Go بتحسين الكود والتحقق دائمًا من الشرط الثاني ، حتى لو كان الخطأ الأول غير صحيح ، لم أجده. أو ربما عيني "ضبابية" وأنا لا أرى أي خطأ واضح؟ أو هل تحتاج إلى تحديد بعض التعليمات الخاصة للمترجم؟ سأكون سعيدًا بتعليقات معقولة.
ملاحظة: نعم ، من أجل المتعة ، قمت بإجراء اختبارات مماثلة على Java 5 و Java 7/8 - كل شيء واضح ، ووقت التنفيذ هو نفسه.