Шароит дар Go ва хусусиятҳои онҳо

Оё шумо фикр мекунед, ки ин ду вариант барои санҷиши шароити дохили як ҳалқа аз ҷиҳати иҷроиш баробаранд?

		
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 ба ҳисоби миёна аст. тақрибан 813 МБ - ин инчунин ба эътимоднокии натиҷа таъсир мерасонад, шумо бояд ҳолатҳои санҷиширо дар диск захира кунед ва ҳама санҷишҳоро барои ҳар як ҳадди аққал дар алоҳидагӣ аз ҳамдигар иҷро кунед.

Ва ҳоло, дар бораи он ки чӣ гуна ин ҳамаро бо хароҷоти камтарин амалӣ кардан мумкин аст, фикр мекунам, ман ба таври худкор санҷиши ҳолатро ислоҳ мекунам

		
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
Натиҷаи 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
Натиҷаи maxEvenDividing: 510 давомнокӣ 114.0066ms
Натиҷаи maxEvenDividing2: 510 давомнокӣ 80.0045ms
Натиҷаи maxEvenConjunction: 510 давомнокӣ 110.0063ms
Натиҷаи maxEvenConjunction2: 510 давомнокӣ 80.0046ms

ҳадди аксар: 1024
Натиҷаи maxEvenDividing: 1022 давомнокӣ 109.0063ms
Натиҷаи maxEvenDividing2: 1022 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 1022 давомнокӣ 111.0063ms
Натиҷаи maxEvenConjunction2: 1022 давомнокӣ 81.0047ms

ҳадди аксар: 2048
Натиҷаи maxEvenDividing: 2046 давомнокӣ 114.0065ms
Натиҷаи maxEvenDividing2: 2046 давомнокӣ 79.0045ms
Натиҷаи maxEvenConjunction: 2046 давомнокӣ 113.0065ms
Натиҷаи maxEvenConjunction2: 2046 давомнокӣ 81.0046ms

ҳадди аксар: 4096
Натиҷаи maxEvenDividing: 4094 давомнокӣ 114.0065ms
Натиҷаи maxEvenDividing2: 4094 давомнокӣ 80.0046ms
Натиҷаи maxEvenConjunction: 4094 давомнокӣ 111.0063ms
Натиҷаи maxEvenConjunction2: 4094 давомнокӣ 78.0045ms

ҳадди аксар: 8192
Натиҷаи maxEvenDividing: 8190 давомнокӣ 107.0062ms
Натиҷаи maxEvenDividing2: 8190 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 8190 давомнокӣ 111.0063ms
Натиҷаи maxEvenConjunction2: 8190 давомнокӣ 77.0044ms

ҳадди аксар: 16384
Натиҷаи maxEvenDividing: 16382 давомнокӣ 109.0063ms
Натиҷаи maxEvenDividing2: 16382 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 16382 давомнокӣ 108.0062ms
Натиҷаи maxEvenConjunction2: 16382 давомнокӣ 77.0044ms

ҳадди аксар: 32768
Натиҷаи maxEvenDividing: 32766 давомнокӣ 112.0064ms
Натиҷаи maxEvenDividing2: 32766 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 32766 давомнокӣ 109.0062ms
Натиҷаи maxEvenConjunction2: 32766 давомнокӣ 78.0045ms

ҳадди аксар: 65536
Натиҷаи maxEvenDividing: 65534 давомнокӣ 109.0062ms
Натиҷаи maxEvenDividing2: 65534 давомнокӣ 75.0043ms
Натиҷаи maxEvenConjunction: 65534 давомнокӣ 109.0063ms
Натиҷаи maxEvenConjunction2: 65534 давомнокӣ 79.0045ms

ҳадди аксар: 131072
Натиҷаи maxEvenDividing: 131070 давомнокӣ 108.0061ms
Натиҷаи maxEvenDividing2: 131070 давомнокӣ 76.0044ms
Натиҷаи maxEvenConjunction: 131070 давомнокӣ 110.0063ms
Натиҷаи maxEvenConjunction2: 131070 давомнокӣ 80.0046ms

ҳадди аксар: 262144
Натиҷаи maxEvenDividing: 262142 давомнокӣ 110.0063ms
Натиҷаи maxEvenDividing2: 262142 давомнокӣ 76.0044ms
Натиҷаи maxEvenConjunction: 262142 давомнокӣ 107.0061ms
Натиҷаи maxEvenConjunction2: 262142 давомнокӣ 78.0044ms

ҳадди аксар: 524288
Натиҷаи maxEvenDividing: 524286 давомнокӣ 109.0062ms
Натиҷаи maxEvenDividing2: 524286 давомнокӣ 78.0045ms
Натиҷаи maxEvenConjunction: 524286 давомнокӣ 109.0062ms
Натиҷаи maxEvenConjunction2: 524286 давомнокӣ 80.0046ms

ҳадди аксар: 1048576
Натиҷаи maxEvenDividing: 1048574 давомнокӣ 109.0063ms
Натиҷаи maxEvenDividing2: 1048574 давомнокӣ 80.0045ms
Натиҷаи maxEvenConjunction: 1048574 давомнокӣ 114.0066ms
Натиҷаи maxEvenConjunction2: 1048574 давомнокӣ 78.0044ms

ҳадди аксар: 2097152
Натиҷаи maxEvenDividing: 2097150 давомнокӣ 111.0064ms
Натиҷаи maxEvenDividing2: 2097150 давомнокӣ 79.0045ms
Натиҷаи maxEvenConjunction: 2097150 давомнокӣ 112.0064ms
Натиҷаи maxEvenConjunction2: 2097150 давомнокӣ 77.0044ms

ҳадди аксар: 4194304
Натиҷаи maxEvenDividing: 4194302 давомнокӣ 111.0063ms
Натиҷаи maxEvenDividing2: 4194302 давомнокӣ 78.0045ms
Натиҷаи maxEvenConjunction: 4194302 давомнокӣ 111.0063ms
Натиҷаи maxEvenConjunction2: 4194302 давомнокӣ 77.0044ms

ҳадди аксар: 8388608
Натиҷаи maxEvenDividing: 8388606 давомнокӣ 109.0062ms
Натиҷаи maxEvenDividing2: 8388606 давомнокӣ 78.0045ms
Натиҷаи maxEvenConjunction: 8388606 давомнокӣ 114.0065ms
Натиҷаи maxEvenConjunction2: 8388606 давомнокӣ 78.0045ms

ҳадди аксар: 16777216
Натиҷаи maxEvenDividing: 16777214 давомнокӣ 109.0062ms
Натиҷаи maxEvenDividing2: 16777214 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 16777214 давомнокӣ 109.0063ms
Натиҷаи maxEvenConjunction2: 16777214 давомнокӣ 77.0044ms

ҳадди аксар: 33554432
Натиҷаи maxEvenDividing: 33554430 давомнокӣ 113.0065ms
Натиҷаи maxEvenDividing2: 33554430 давомнокӣ 78.0045ms
Натиҷаи maxEvenConjunction: 33554430 давомнокӣ 110.0063ms
Натиҷаи maxEvenConjunction2: 33554430 давомнокӣ 80.0045ms

ҳадди аксар: 67108864
Натиҷаи maxEvenDividing: 67108860 давомнокӣ 112.0064ms
Натиҷаи maxEvenDividing2: 67108860 давомнокӣ 77.0044ms
Натиҷаи maxEvenConjunction: 67108860 давомнокӣ 112.0064ms
Натиҷаи maxEvenConjunction2: 67108860 давомнокӣ 80.0046ms

ҳадди аксар: 134217728
Натиҷаи maxEvenDividing: 134217726 давомнокӣ 109.0063ms
Натиҷаи maxEvenDividing2: 134217726 давомнокӣ 78.0044ms
Натиҷаи maxEvenConjunction: 134217726 давомнокӣ 114.0065ms
Натиҷаи maxEvenConjunction2: 134217726 давомнокӣ 81.0047ms

ҳадди аксар: 268435456
Натиҷаи maxEvenDividing: 268435446 давомнокӣ 111.0064ms
Натиҷаи maxEvenDividing2: 268435446 давомнокӣ 79.0045ms
Натиҷаи maxEvenConjunction: 268435446 давомнокӣ 114.0065ms
Натиҷаи maxEvenConjunction2: 268435446 давомнокӣ 79.0045ms

ҳадди аксар: 536870912
Натиҷаи maxEvenDividing: 536870910 давомнокӣ 107.0062ms
Натиҷаи maxEvenDividing2: 536870910 давомнокӣ 76.0043ms
Натиҷаи maxEvenConjunction: 536870910 давомнокӣ 109.0062ms
Натиҷаи maxEvenConjunction2: 536870910 давомнокӣ 80.0046ms

Ман шарҳи возеҳе ёфта натавонистам, ки чаро компилятори Go кодро оптимизатсия намекунад ва ҳамеша шарти дуюмро тафтиш мекунад, ҳатто агар шарти аввал нодуруст бошад. Ё шояд чашмони ман норавшананд ва ман ягон хатои аёнро намебинам? Ё ба шумо лозим аст, ки ба тартибдиҳанда дастурҳои махсус пешниҳод кунед? Ман аз шарҳҳои оқилона шод мешудам.

PS: Бале, танҳо барои фароғат, ман озмоишҳои шабеҳро дар Java 5 ва Java 7/8 гузаронидам - ​​ҳама чиз равшан аст, вақти иҷро яксон аст.

Манбаъ: will.com

Илова Эзоҳ