Kundizzjonijiet fil Go u l-kwirks tagħhom

Taħseb li dawn iż-żewġ għażliet għall-ittestjar tal-kundizzjonijiet ġewwa linja huma ekwivalenti fil-prestazzjoni?

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


Kollox beda b'"brain warm-up"; kelli nagħti eżempju ta' tfittxija ottimali għall-akbar numru pari f'firxa ta' numri interi [-x....x]. Kont qed nistaqsi kemm tkun prestazzjoni aħjar jekk użajt multiplikazzjoni loġika b'1 biex nifhem jekk numru huwiex ugwali jew le.


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

L-esperjenza tiegħi tal-ipprogrammar f'Go mhix estensiva ħafna, ftit aktar minn sena u nofs, użajtha, għalkemm ħafna drabi, iżda purament għal skopijiet utilitarji (sewwa, forsi ħlief għal proġett wieħed relatat ma' servizz http b'tagħbija għolja), għalhekk Bdejt biha. Iftaħ GoLand u ikteb test sempliċi


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
}

Ikollna riżultat li juri li iktar ma jkun għoli l-limitu, aktar spiss jidhru varjazzjonijiet fil-prestazzjoni.

Qabbelmax 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

Huwa ċar li f'dan il-każ, għal limiti differenti għandna settijiet differenti ta 'dejta tat-test, it-tagħbija tal-proċessur (fuq il-laptop tiegħi i5-2540M) tvarja madwar 20..30%, il-memorja okkupata mill-applikazzjoni li taħdem minn GoLand hija medja. madwar 813MB - dan jaffettwa wkoll l-affidabbiltà tar-riżultat, għandek bżonn tiffranka l-każijiet tat-test fuq disk u tmexxi t-testijiet kollha għal kull limitu iżolat minn xulxin.

U issa, naħseb dwar kif nimplimenta dan kollu bi spejjeż minimi, nikkoreġi awtomatikament il-kontroll tal-kundizzjoni

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

fuq

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

Erġa nagħmel it-testijiet... u nieqaf nifhem xejn :)

Iż-żmien mqatta 'fuq l-eżekuzzjoni jibda jvarja mhux b'perċentwali/frazzjonijiet ta' fil-mija, iżda b'10..15%. Malajr inżid 2 testijiet oħra:

		
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
}

Imexxiha u nġib din l-istampa:kapaċità tal-firxa inizjali: 100000000

limitu massimu: 128
maxEvenDividing riżultat: 126 tul 116.0066ms
maxEvenDividing2 riżultat: 126 tul 79.0045ms
maxEvenConjunction riżultat: 126 tul 114.0065ms
maxEvenConjunction2 riżultat: 126 tul 83.0048ms

limitu massimu: 256
maxEvenDividing riżultat: 254 tul 111.0063ms
maxEvenDividing2 riżultat: 254 tul 77.0044ms
maxEvenConjunction riżultat: 254 tul 110.0063ms
maxEvenConjunction2 riżultat: 254 tul 80.0046ms

limitu massimu: 512
maxEvenDividing riżultat: 510 tul 114.0066ms
maxEvenDividing2 riżultat: 510 tul 80.0045ms
maxEvenConjunction riżultat: 510 tul 110.0063ms
maxEvenConjunction2 riżultat: 510 tul 80.0046ms

limitu massimu: 1024
maxEvenDividing riżultat: 1022 tul 109.0063ms
maxEvenDividing2 riżultat: 1022 tul 77.0044ms
maxEvenConjunction riżultat: 1022 tul 111.0063ms
maxEvenConjunction2 riżultat: 1022 tul 81.0047ms

limitu massimu: 2048
maxEvenDividing riżultat: 2046 tul 114.0065ms
maxEvenDividing2 riżultat: 2046 tul 79.0045ms
maxEvenConjunction riżultat: 2046 tul 113.0065ms
maxEvenConjunction2 riżultat: 2046 tul 81.0046ms

limitu massimu: 4096
maxEvenDividing riżultat: 4094 tul 114.0065ms
maxEvenDividing2 riżultat: 4094 tul 80.0046ms
maxEvenConjunction riżultat: 4094 tul 111.0063ms
maxEvenConjunction2 riżultat: 4094 tul 78.0045ms

limitu massimu: 8192
maxEvenDividing riżultat: 8190 tul 107.0062ms
maxEvenDividing2 riżultat: 8190 tul 77.0044ms
maxEvenConjunction riżultat: 8190 tul 111.0063ms
maxEvenConjunction2 riżultat: 8190 tul 77.0044ms

limitu massimu: 16384
maxEvenDividing riżultat: 16382 tul 109.0063ms
maxEvenDividing2 riżultat: 16382 tul 77.0044ms
maxEvenConjunction riżultat: 16382 tul 108.0062ms
maxEvenConjunction2 riżultat: 16382 tul 77.0044ms

limitu massimu: 32768
maxEvenDividing riżultat: 32766 tul 112.0064ms
maxEvenDividing2 riżultat: 32766 tul 77.0044ms
maxEvenConjunction riżultat: 32766 tul 109.0062ms
maxEvenConjunction2 riżultat: 32766 tul 78.0045ms

limitu massimu: 65536
maxEvenDividing riżultat: 65534 tul 109.0062ms
maxEvenDividing2 riżultat: 65534 tul 75.0043ms
maxEvenConjunction riżultat: 65534 tul 109.0063ms
maxEvenConjunction2 riżultat: 65534 tul 79.0045ms

limitu massimu: 131072
maxEvenDividing riżultat: 131070 tul 108.0061ms
maxEvenDividing2 riżultat: 131070 tul 76.0044ms
maxEvenConjunction riżultat: 131070 tul 110.0063ms
maxEvenConjunction2 riżultat: 131070 tul 80.0046ms

limitu massimu: 262144
maxEvenDividing riżultat: 262142 tul 110.0063ms
maxEvenDividing2 riżultat: 262142 tul 76.0044ms
maxEvenConjunction riżultat: 262142 tul 107.0061ms
maxEvenConjunction2 riżultat: 262142 tul 78.0044ms

limitu massimu: 524288
maxEvenDividing riżultat: 524286 tul 109.0062ms
maxEvenDividing2 riżultat: 524286 tul 78.0045ms
maxEvenConjunction riżultat: 524286 tul 109.0062ms
maxEvenConjunction2 riżultat: 524286 tul 80.0046ms

limitu massimu: 1048576
maxEvenDividing riżultat: 1048574 tul 109.0063ms
maxEvenDividing2 riżultat: 1048574 tul 80.0045ms
maxEvenConjunction riżultat: 1048574 tul 114.0066ms
maxEvenConjunction2 riżultat: 1048574 tul 78.0044ms

limitu massimu: 2097152
maxEvenDividing riżultat: 2097150 tul 111.0064ms
maxEvenDividing2 riżultat: 2097150 tul 79.0045ms
maxEvenConjunction riżultat: 2097150 tul 112.0064ms
maxEvenConjunction2 riżultat: 2097150 tul 77.0044ms

limitu massimu: 4194304
maxEvenDividing riżultat: 4194302 tul 111.0063ms
maxEvenDividing2 riżultat: 4194302 tul 78.0045ms
maxEvenConjunction riżultat: 4194302 tul 111.0063ms
maxEvenConjunction2 riżultat: 4194302 tul 77.0044ms

limitu massimu: 8388608
maxEvenDividing riżultat: 8388606 tul 109.0062ms
maxEvenDividing2 riżultat: 8388606 tul 78.0045ms
maxEvenConjunction riżultat: 8388606 tul 114.0065ms
maxEvenConjunction2 riżultat: 8388606 tul 78.0045ms

limitu massimu: 16777216
maxEvenDividing riżultat: 16777214 tul 109.0062ms
maxEvenDividing2 riżultat: 16777214 tul 77.0044ms
maxEvenConjunction riżultat: 16777214 tul 109.0063ms
maxEvenConjunction2 riżultat: 16777214 tul 77.0044ms

limitu massimu: 33554432
maxEvenDividing riżultat: 33554430 tul 113.0065ms
maxEvenDividing2 riżultat: 33554430 tul 78.0045ms
maxEvenConjunction riżultat: 33554430 tul 110.0063ms
maxEvenConjunction2 riżultat: 33554430 tul 80.0045ms

limitu massimu: 67108864
maxEvenDividing riżultat: 67108860 tul 112.0064ms
maxEvenDividing2 riżultat: 67108860 tul 77.0044ms
maxEvenConjunction riżultat: 67108860 tul 112.0064ms
maxEvenConjunction2 riżultat: 67108860 tul 80.0046ms

limitu massimu: 134217728
maxEvenDividing riżultat: 134217726 tul 109.0063ms
maxEvenDividing2 riżultat: 134217726 tul 78.0044ms
maxEvenConjunction riżultat: 134217726 tul 114.0065ms
maxEvenConjunction2 riżultat: 134217726 tul 81.0047ms

limitu massimu: 268435456
maxEvenDividing riżultat: 268435446 tul 111.0064ms
maxEvenDividing2 riżultat: 268435446 tul 79.0045ms
maxEvenConjunction riżultat: 268435446 tul 114.0065ms
maxEvenConjunction2 riżultat: 268435446 tul 79.0045ms

limitu massimu: 536870912
maxEvenDividing riżultat: 536870910 tul 107.0062ms
maxEvenDividing2 riżultat: 536870910 tul 76.0043ms
maxEvenConjunction riżultat: 536870910 tul 109.0062ms
maxEvenConjunction2 riżultat: 536870910 tul 80.0046ms

Ma stajtx insib spjegazzjoni ċara għaliex il-kompilatur Go ma jottimizzax il-kodiċi u dejjem jiċċekkja t-tieni kundizzjoni, anki jekk l-ewwel waħda hija falza. Jew forsi għajnejja huma sempliċement imċajpra u ma nara l-ebda żball ovvju? Jew għandek bżonn tipprovdi xi struzzjonijiet speċjali lill-kompilatur? Inkun kuntent għal kummenti sensibbli.

PS: Iva, biss għall-gost, għamilt testijiet simili fuq Java 5 u Java 7/8 - kollox huwa ċar, il-ħin ta 'eżekuzzjoni huwa l-istess.

Sors: www.habr.com

Żid kumment