په تګ کې شرایط او د دوی نرخونه

ایا تاسو فکر کوئ چې د لوپ دننه د شرایطو ازموینې لپاره دا دوه اختیارونه په فعالیت کې مساوي دي؟

		
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

په Go کې زما د برنامه کولو تجربه خورا پراخه نده ، یوازې یو نیم کال کې ، ما دا کارولې ، که څه هم ډیری وختونه ، مګر په بشپړ ډول د ګټورو موخو لپاره (ښه ، شاید د یوې پروژې پرته چې د لوړ بار 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٪ لخوا. زه په چټکۍ سره دوه نورې ازموینې اضافه کوم:

		
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
maxEvenDivding2 پایله: 126 موده 79.0045ms
maxEven Conjunction پایله: 126 موده 114.0065ms
maxEvenConjunction2 پایله: 126 موده 83.0048ms

اعظمي حد: 256
maxEvenDividing پایله: 254 موده 111.0063ms
maxEvenDivding2 پایله: 254 موده 77.0044ms
maxEven Conjunction پایله: 254 موده 110.0063ms
maxEvenConjunction2 پایله: 254 موده 80.0046ms

اعظمي حد: 512
maxEvenDividing پایله: 510 موده 114.0066ms
maxEvenDivding2 پایله: 510 موده 80.0045ms
maxEven Conjunction پایله: 510 موده 110.0063ms
maxEvenConjunction2 پایله: 510 موده 80.0046ms

اعظمي حد: 1024
maxEvenDividing پایله: 1022 موده 109.0063ms
maxEvenDivding2 پایله: 1022 موده 77.0044ms
maxEven Conjunction پایله: 1022 موده 111.0063ms
maxEvenConjunction2 پایله: 1022 موده 81.0047ms

اعظمي حد: 2048
maxEvenDividing پایله: 2046 موده 114.0065ms
maxEvenDivding2 پایله: 2046 موده 79.0045ms
maxEven Conjunction پایله: 2046 موده 113.0065ms
maxEvenConjunction2 پایله: 2046 موده 81.0046ms

اعظمي حد: 4096
maxEvenDividing پایله: 4094 موده 114.0065ms
maxEvenDivding2 پایله: 4094 موده 80.0046ms
maxEven Conjunction پایله: 4094 موده 111.0063ms
maxEvenConjunction2 پایله: 4094 موده 78.0045ms

اعظمي حد: 8192
maxEvenDividing پایله: 8190 موده 107.0062ms
maxEvenDivding2 پایله: 8190 موده 77.0044ms
maxEven Conjunction پایله: 8190 موده 111.0063ms
maxEvenConjunction2 پایله: 8190 موده 77.0044ms

اعظمي حد: 16384
maxEvenDividing پایله: 16382 موده 109.0063ms
maxEvenDivding2 پایله: 16382 موده 77.0044ms
maxEven Conjunction پایله: 16382 موده 108.0062ms
maxEvenConjunction2 پایله: 16382 موده 77.0044ms

اعظمي حد: 32768
maxEvenDividing پایله: 32766 موده 112.0064ms
maxEvenDivding2 پایله: 32766 موده 77.0044ms
maxEven Conjunction پایله: 32766 موده 109.0062ms
maxEvenConjunction2 پایله: 32766 موده 78.0045ms

اعظمي حد: 65536
maxEvenDividing پایله: 65534 موده 109.0062ms
maxEvenDivding2 پایله: 65534 موده 75.0043ms
maxEven Conjunction پایله: 65534 موده 109.0063ms
maxEvenConjunction2 پایله: 65534 موده 79.0045ms

اعظمي حد: 131072
maxEvenDividing پایله: 131070 موده 108.0061ms
maxEvenDivding2 پایله: 131070 موده 76.0044ms
maxEven Conjunction پایله: 131070 موده 110.0063ms
maxEvenConjunction2 پایله: 131070 موده 80.0046ms

اعظمي حد: 262144
maxEvenDividing پایله: 262142 موده 110.0063ms
maxEvenDivding2 پایله: 262142 موده 76.0044ms
maxEven Conjunction پایله: 262142 موده 107.0061ms
maxEvenConjunction2 پایله: 262142 موده 78.0044ms

اعظمي حد: 524288
maxEvenDividing پایله: 524286 موده 109.0062ms
maxEvenDivding2 پایله: 524286 موده 78.0045ms
maxEven Conjunction پایله: 524286 موده 109.0062ms
maxEvenConjunction2 پایله: 524286 موده 80.0046ms

اعظمي حد: 1048576
maxEvenDividing پایله: 1048574 موده 109.0063ms
maxEvenDivding2 پایله: 1048574 موده 80.0045ms
maxEven Conjunction پایله: 1048574 موده 114.0066ms
maxEvenConjunction2 پایله: 1048574 موده 78.0044ms

اعظمي حد: 2097152
maxEvenDividing پایله: 2097150 موده 111.0064ms
maxEvenDivding2 پایله: 2097150 موده 79.0045ms
maxEven Conjunction پایله: 2097150 موده 112.0064ms
maxEvenConjunction2 پایله: 2097150 موده 77.0044ms

اعظمي حد: 4194304
maxEvenDividing پایله: 4194302 موده 111.0063ms
maxEvenDivding2 پایله: 4194302 موده 78.0045ms
maxEven Conjunction پایله: 4194302 موده 111.0063ms
maxEvenConjunction2 پایله: 4194302 موده 77.0044ms

اعظمي حد: 8388608
maxEvenDividing پایله: 8388606 موده 109.0062ms
maxEvenDivding2 پایله: 8388606 موده 78.0045ms
maxEven Conjunction پایله: 8388606 موده 114.0065ms
maxEvenConjunction2 پایله: 8388606 موده 78.0045ms

اعظمي حد: 16777216
maxEvenDividing پایله: 16777214 موده 109.0062ms
maxEvenDivding2 پایله: 16777214 موده 77.0044ms
maxEven Conjunction پایله: 16777214 موده 109.0063ms
maxEvenConjunction2 پایله: 16777214 موده 77.0044ms

اعظمي حد: 33554432
maxEvenDividing پایله: 33554430 موده 113.0065ms
maxEvenDivding2 پایله: 33554430 موده 78.0045ms
maxEven Conjunction پایله: 33554430 موده 110.0063ms
maxEvenConjunction2 پایله: 33554430 موده 80.0045ms

اعظمي حد: 67108864
maxEvenDividing پایله: 67108860 موده 112.0064ms
maxEvenDivding2 پایله: 67108860 موده 77.0044ms
maxEven Conjunction پایله: 67108860 موده 112.0064ms
maxEvenConjunction2 پایله: 67108860 موده 80.0046ms

اعظمي حد: 134217728
maxEvenDividing پایله: 134217726 موده 109.0063ms
maxEvenDivding2 پایله: 134217726 موده 78.0044ms
maxEven Conjunction پایله: 134217726 موده 114.0065ms
maxEvenConjunction2 پایله: 134217726 موده 81.0047ms

اعظمي حد: 268435456
maxEvenDividing پایله: 268435446 موده 111.0064ms
maxEvenDivding2 پایله: 268435446 موده 79.0045ms
maxEven Conjunction پایله: 268435446 موده 114.0065ms
maxEvenConjunction2 پایله: 268435446 موده 79.0045ms

اعظمي حد: 536870912
maxEvenDividing پایله: 536870910 موده 107.0062ms
maxEvenDivding2 پایله: 536870910 موده 76.0043ms
maxEven Conjunction پایله: 536870910 موده 109.0062ms
maxEvenConjunction2 پایله: 536870910 موده 80.0046ms

زه روښانه توضیح نشم موندلی چې ولې د Go کمپیلر کوډ نه اصلاح کوي او تل دوهم حالت ګوري ، حتی که لومړی یې غلط وي. یا شاید زما سترګې یوازې تیاره وي او زه کومه ښکاره غلطي نه وینم؟ یا تاسو اړتیا لرئ چې تالیف کونکي ته ځینې ځانګړي لارښوونې چمتو کړئ؟ زه به د معقول نظرونو لپاره خوښ شم.

PS: هو، یوازې د ساتیرۍ لپاره، ما په جاوا 5 او جاوا 7/8 کې ورته ازموینې ترسره کړې - هرڅه روښانه دي، د اعدام وخت ورته دی.

سرچینه: www.habr.com

Add a comment