گو میں حالات اور ان کے نرالا

کیا آپ کو لگتا ہے کہ لوپ کے اندر حالات کی جانچ کے لیے یہ دو اختیارات کارکردگی میں برابر ہیں؟

		
if a > b && c*2 > d {
	....
}
// и
if a <= b  { 
  continue;
}
if c*2 > d {
 ....
}


یہ سب ایک "برین وارم اپ" کے ساتھ شروع ہوا؛ مجھے انٹیجرز [-x....x] کی ایک صف میں سب سے بڑے ہموار نمبر کے لیے بہترین تلاش کی مثال دینا تھی۔ میں سوچ رہا تھا کہ کتنی بہتر کارکردگی ہو گی اگر میں 1 سے منطقی ضرب استعمال کروں تاکہ یہ معلوم کیا جا سکے کہ آیا کوئی عدد ہموار ہے یا نہیں۔


//у четных чисел последний бит всегда равен 0
value & 1 == 0
//vs классический метод
value % 2 == 0

گو میں میرا پروگرامنگ کا تجربہ بہت وسیع نہیں ہے، صرف ڈیڑھ سال سے زیادہ، میں نے اسے استعمال کیا، اگرچہ اکثر، لیکن خالصتاً مفید مقاصد کے لیے (اچھا، شاید ایک پروجیکٹ کے علاوہ جو زیادہ بوجھ والی HTTP سروس سے متعلق ہے)، اس لیے میں اس کے ساتھ شروع کیا. GoLand کھولیں اور ایک سادہ ٹیسٹ لکھیں۔


package main
import (
	"fmt"
	"log"
	"math"
	"math/rand"
	"time"
)
const size = 100000000 //math.MaxInt32*2
type Result struct {
	Name     string
	Duration time.Duration
	Value    int32
}

func main() {
	log.Println("initial array capacity: " + fmt.Sprint(size))
	var maxValue int32
        // Будем варьировать диапазон чисел от минимального 
        // до максимального. Чем меньше диапазон, тем больше 
        // процессорного времени будет уходить на операцию 
        // сравнения текущего числа, с ранее найденным и наоборот
	for maxValue = 128; maxValue < math.MaxInt32/2+1; maxValue = maxValue * 2 {
		test(maxValue)
	}
}

func test(maxValue int32) {
	log.Println("max threshold: " + fmt.Sprint(maxValue))
	arr := make([]int32, size)
	for i := range arr {
		arr[i] = rand.Int31n(maxValue)
                // в тестовых данных нам нужны и отрицательные числа 
		sign := rand.Intn(2)
		if sign == 1 {
			arr[i] = -arr[i]
		}
	}

        // запускаем тест "деление с остатком"
	result := maxEvenDividing("maxEvenDividing", arr)
	log.Printf(result.Name+"t result: "+fmt.Sprint(result.Value)+"ttduration %s", result.Duration)

        // запускаем тест "конъюнкции"
	result = maxEvenConjunction("maxEvenConjunction", arr)
	log.Printf(result.Name+"t result: "+fmt.Sprint(result.Value)+"ttduration %s", result.Duration)
}

func maxEvenDividing(name string, arr []int32) Result {
	start := time.Now()
	var current int32 = math.MinInt32
	for _, value := range arr {
		if value > current && value%2 == 0 {
			current = value
		}
	}
	duration := time.Since(start)
	result := Result{name, duration, current}
	return result
}

func maxEvenConjunction(name string, arr []int32) Result {
	start := time.Now()
	var current int32 = math.MinInt32
	for _, value := range arr {
		if value > current && value&1 == 0 {
			current = value
		}
	}
	duration := time.Since(start)
	result := Result{name, duration, current}
	return result
}

ہمیں ایک نتیجہ ملتا ہے جو ظاہر کرتا ہے کہ حد جتنی زیادہ ہوگی، کارکردگی میں اکثر اتار چڑھاؤ ظاہر ہوتا ہے۔

موازنہ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 سے چلنے والی ایپلی کیشن کے زیر قبضہ میموری اوسطاً ہوتی ہے۔ 813MB کے بارے میں - یہ نتیجہ کی وشوسنییتا کو بھی متاثر کرتا ہے، آپ کو ٹیسٹ کیسز کو ڈسک پر محفوظ کرنے اور ہر حد کے لیے ایک دوسرے سے الگ تھلگ رہتے ہوئے تمام ٹیسٹ چلانے کی ضرورت ہے۔

اور اب، اس سب کو کم سے کم لاگت کے ساتھ کیسے لاگو کیا جائے اس کے بارے میں سوچتے ہوئے، میں خود بخود کنڈیشن چیک کو درست کرتا ہوں۔

		
if value > current && value&1 == 0 {
	current = value
}

پر

		
if value <= current {
        continue;
}
if value&1 == 0 {
	current = value
}

میں دوبارہ ٹیسٹ چلاتا ہوں ... اور میں کچھ بھی سمجھنا چھوڑ دیتا ہوں :)

عمل درآمد پر گزارا ہوا وقت فی صد کے فیصد/فرکشن سے نہیں بلکہ 10..15% سے مختلف ہونا شروع ہوتا ہے۔ میں جلدی سے 2 مزید ٹیسٹ شامل کرتا ہوں:

		
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
maxEvenDividing نتیجہ: 126 دورانیہ 116.0066ms
maxEvenDiving2 نتیجہ: 126 دورانیہ 79.0045ms
maxEvenConjunction نتیجہ: 126 دورانیہ 114.0065ms
maxEvenConjunction2 نتیجہ: 126 دورانیہ 83.0048ms

زیادہ سے زیادہ حد: 256
maxEvenDividing نتیجہ: 254 دورانیہ 111.0063ms
maxEvenDiving2 نتیجہ: 254 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 254 دورانیہ 110.0063ms
maxEvenConjunction2 نتیجہ: 254 دورانیہ 80.0046ms

زیادہ سے زیادہ حد: 512
maxEvenDividing نتیجہ: 510 دورانیہ 114.0066ms
maxEvenDiving2 نتیجہ: 510 دورانیہ 80.0045ms
maxEvenConjunction نتیجہ: 510 دورانیہ 110.0063ms
maxEvenConjunction2 نتیجہ: 510 دورانیہ 80.0046ms

زیادہ سے زیادہ حد: 1024
maxEvenDividing نتیجہ: 1022 دورانیہ 109.0063ms
maxEvenDiving2 نتیجہ: 1022 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 1022 دورانیہ 111.0063ms
maxEvenConjunction2 نتیجہ: 1022 دورانیہ 81.0047ms

زیادہ سے زیادہ حد: 2048
maxEvenDividing نتیجہ: 2046 دورانیہ 114.0065ms
maxEvenDiving2 نتیجہ: 2046 دورانیہ 79.0045ms
maxEvenConjunction نتیجہ: 2046 دورانیہ 113.0065ms
maxEvenConjunction2 نتیجہ: 2046 دورانیہ 81.0046ms

زیادہ سے زیادہ حد: 4096
maxEvenDividing نتیجہ: 4094 دورانیہ 114.0065ms
maxEvenDiving2 نتیجہ: 4094 دورانیہ 80.0046ms
maxEvenConjunction نتیجہ: 4094 دورانیہ 111.0063ms
maxEvenConjunction2 نتیجہ: 4094 دورانیہ 78.0045ms

زیادہ سے زیادہ حد: 8192
maxEvenDividing نتیجہ: 8190 دورانیہ 107.0062ms
maxEvenDiving2 نتیجہ: 8190 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 8190 دورانیہ 111.0063ms
maxEvenConjunction2 نتیجہ: 8190 دورانیہ 77.0044ms

زیادہ سے زیادہ حد: 16384
maxEvenDividing نتیجہ: 16382 دورانیہ 109.0063ms
maxEvenDiving2 نتیجہ: 16382 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 16382 دورانیہ 108.0062ms
maxEvenConjunction2 نتیجہ: 16382 دورانیہ 77.0044ms

زیادہ سے زیادہ حد: 32768
maxEvenDividing نتیجہ: 32766 دورانیہ 112.0064ms
maxEvenDiving2 نتیجہ: 32766 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 32766 دورانیہ 109.0062ms
maxEvenConjunction2 نتیجہ: 32766 دورانیہ 78.0045ms

زیادہ سے زیادہ حد: 65536
maxEvenDividing نتیجہ: 65534 دورانیہ 109.0062ms
maxEvenDiving2 نتیجہ: 65534 دورانیہ 75.0043ms
maxEvenConjunction نتیجہ: 65534 دورانیہ 109.0063ms
maxEvenConjunction2 نتیجہ: 65534 دورانیہ 79.0045ms

زیادہ سے زیادہ حد: 131072
maxEvenDividing نتیجہ: 131070 دورانیہ 108.0061ms
maxEvenDiving2 نتیجہ: 131070 دورانیہ 76.0044ms
maxEvenConjunction نتیجہ: 131070 دورانیہ 110.0063ms
maxEvenConjunction2 نتیجہ: 131070 دورانیہ 80.0046ms

زیادہ سے زیادہ حد: 262144
maxEvenDividing نتیجہ: 262142 دورانیہ 110.0063ms
maxEvenDiving2 نتیجہ: 262142 دورانیہ 76.0044ms
maxEvenConjunction نتیجہ: 262142 دورانیہ 107.0061ms
maxEvenConjunction2 نتیجہ: 262142 دورانیہ 78.0044ms

زیادہ سے زیادہ حد: 524288
maxEvenDividing نتیجہ: 524286 دورانیہ 109.0062ms
maxEvenDiving2 نتیجہ: 524286 دورانیہ 78.0045ms
maxEvenConjunction نتیجہ: 524286 دورانیہ 109.0062ms
maxEvenConjunction2 نتیجہ: 524286 دورانیہ 80.0046ms

زیادہ سے زیادہ حد: 1048576
maxEvenDividing نتیجہ: 1048574 دورانیہ 109.0063ms
maxEvenDiving2 نتیجہ: 1048574 دورانیہ 80.0045ms
maxEvenConjunction نتیجہ: 1048574 دورانیہ 114.0066ms
maxEvenConjunction2 نتیجہ: 1048574 دورانیہ 78.0044ms

زیادہ سے زیادہ حد: 2097152
maxEvenDividing نتیجہ: 2097150 دورانیہ 111.0064ms
maxEvenDiving2 نتیجہ: 2097150 دورانیہ 79.0045ms
maxEvenConjunction نتیجہ: 2097150 دورانیہ 112.0064ms
maxEvenConjunction2 نتیجہ: 2097150 دورانیہ 77.0044ms

زیادہ سے زیادہ حد: 4194304
maxEvenDividing نتیجہ: 4194302 دورانیہ 111.0063ms
maxEvenDiving2 نتیجہ: 4194302 دورانیہ 78.0045ms
maxEvenConjunction نتیجہ: 4194302 دورانیہ 111.0063ms
maxEvenConjunction2 نتیجہ: 4194302 دورانیہ 77.0044ms

زیادہ سے زیادہ حد: 8388608
maxEvenDividing نتیجہ: 8388606 دورانیہ 109.0062ms
maxEvenDiving2 نتیجہ: 8388606 دورانیہ 78.0045ms
maxEvenConjunction نتیجہ: 8388606 دورانیہ 114.0065ms
maxEvenConjunction2 نتیجہ: 8388606 دورانیہ 78.0045ms

زیادہ سے زیادہ حد: 16777216
maxEvenDividing نتیجہ: 16777214 دورانیہ 109.0062ms
maxEvenDiving2 نتیجہ: 16777214 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 16777214 دورانیہ 109.0063ms
maxEvenConjunction2 نتیجہ: 16777214 دورانیہ 77.0044ms

زیادہ سے زیادہ حد: 33554432
maxEvenDividing نتیجہ: 33554430 دورانیہ 113.0065ms
maxEvenDiving2 نتیجہ: 33554430 دورانیہ 78.0045ms
maxEvenConjunction نتیجہ: 33554430 دورانیہ 110.0063ms
maxEvenConjunction2 نتیجہ: 33554430 دورانیہ 80.0045ms

زیادہ سے زیادہ حد: 67108864
maxEvenDividing نتیجہ: 67108860 دورانیہ 112.0064ms
maxEvenDiving2 نتیجہ: 67108860 دورانیہ 77.0044ms
maxEvenConjunction نتیجہ: 67108860 دورانیہ 112.0064ms
maxEvenConjunction2 نتیجہ: 67108860 دورانیہ 80.0046ms

زیادہ سے زیادہ حد: 134217728
maxEvenDividing نتیجہ: 134217726 دورانیہ 109.0063ms
maxEvenDiving2 نتیجہ: 134217726 دورانیہ 78.0044ms
maxEvenConjunction نتیجہ: 134217726 دورانیہ 114.0065ms
maxEvenConjunction2 نتیجہ: 134217726 دورانیہ 81.0047ms

زیادہ سے زیادہ حد: 268435456
maxEvenDividing نتیجہ: 268435446 دورانیہ 111.0064ms
maxEvenDiving2 نتیجہ: 268435446 دورانیہ 79.0045ms
maxEvenConjunction نتیجہ: 268435446 دورانیہ 114.0065ms
maxEvenConjunction2 نتیجہ: 268435446 دورانیہ 79.0045ms

زیادہ سے زیادہ حد: 536870912
maxEvenDividing نتیجہ: 536870910 دورانیہ 107.0062ms
maxEvenDiving2 نتیجہ: 536870910 دورانیہ 76.0043ms
maxEvenConjunction نتیجہ: 536870910 دورانیہ 109.0062ms
maxEvenConjunction2 نتیجہ: 536870910 دورانیہ 80.0046ms

مجھے اس کی واضح وضاحت نہیں مل سکی کہ گو کمپائلر کوڈ کو کیوں بہتر نہیں کرتا ہے اور ہمیشہ دوسری شرط کو چیک کرتا ہے، چاہے پہلی غلط ہو۔ یا شاید میری آنکھیں دھندلی ہیں اور مجھے کوئی واضح غلطی نظر نہیں آرہی؟ یا کیا آپ کو مرتب کرنے والے کو کچھ خاص ہدایات دینے کی ضرورت ہے؟ میں سمجھدار تبصرے کے لئے خوش ہوں گے.

PS: ہاں، صرف تفریح ​​کے لیے، میں نے جاوا 5 اور جاوا 7/8 پر اسی طرح کے ٹیسٹ چلائے - سب کچھ واضح ہے، عمل درآمد کا وقت ایک جیسا ہے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں