Toestande in Go en hul eienaardighede

Dink jy hierdie twee opsies vir die toets van toestande binne 'n lus is gelykstaande in prestasie?

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


Dit het alles begin met 'n "breinopwarming"; ek moes 'n voorbeeld gee van 'n optimale soektog na die grootste ewe getal in 'n reeks heelgetalle [-x....x]. Ek het gewonder hoeveel beter prestasie sou wees as ek logiese vermenigvuldiging met 1 gebruik om uit te vind of 'n getal ewe is of nie.


//Ρƒ Ρ‡Π΅Ρ‚Π½Ρ‹Ρ… чисСл послСдний Π±ΠΈΡ‚ всСгда Ρ€Π°Π²Π΅Π½ 0
value & 1 == 0
//vs классичСский ΠΌΠ΅Ρ‚ΠΎΠ΄
value % 2 == 0

My programmeringservaring in Go is nie baie uitgebreid nie, net meer as 'n jaar en 'n half, ek het dit gebruik, hoewel dikwels, maar suiwer vir utilitΓͺre doeleindes (wel, miskien behalwe vir een projek wat verband hou met 'n hoΓ«-lading http-diens), so ek daarmee begin het. Maak GoLand oop en skryf 'n eenvoudige toets


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
}

Ons kry 'n resultaat wat toon dat hoe hoΓ«r die drempel, hoe meer dikwels verskyn fluktuasies in prestasie.

vergelykmax 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

Dit is duidelik dat in hierdie geval, vir verskillende drempels ons verskillende stelle toetsdata het, die verwerkerlading (op my i5-2540M skootrekenaar) wissel rondom 20..30%, die geheue wat beset word deur die toepassing wat vanaf GoLand loop, is gemiddeld ongeveer 813MB - dit beΓ―nvloed ook die betroubaarheid van die resultaat, jy moet toetsgevalle op skyf stoor en alle toetse vir elke drempel in isolasie van mekaar uitvoer.

En nou, terwyl ek dink oor hoe om dit alles met minimale koste te implementeer, korrigeer ek die toestandkontrole outomaties

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

op

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

Ek voer die toetse weer ... en ek hou op om iets te verstaan ​​:)

Die tyd wat aan uitvoering bestee word, begin nie meer verskil met persentasies/breukdele van 'n persent nie, maar met 10..15%.Ek voeg vinnig nog 2 toetse by:

		
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
}

Ek hardloop dit en kry hierdie prentjie:aanvanklike skikking kapasiteit: 100000000

maksimum drempel: 128
maxEvenDividing resultaat: 126 duur 116.0066ms
maxEvenDividing2 resultaat: 126 duur 79.0045ms
maxEvenConjunction resultaat: 126 duur 114.0065ms
maxEvenConjunction2 resultaat: 126 duur 83.0048ms

maksimum drempel: 256
maxEvenDividing resultaat: 254 duur 111.0063ms
maxEvenDividing2 resultaat: 254 duur 77.0044ms
maxEvenConjunction resultaat: 254 duur 110.0063ms
maxEvenConjunction2 resultaat: 254 duur 80.0046ms

maksimum drempel: 512
maxEvenDividing resultaat: 510 duur 114.0066ms
maxEvenDividing2 resultaat: 510 duur 80.0045ms
maxEvenConjunction resultaat: 510 duur 110.0063ms
maxEvenConjunction2 resultaat: 510 duur 80.0046ms

maksimum drempel: 1024
maxEvenDividing resultaat: 1022 duur 109.0063ms
maxEvenDividing2 resultaat: 1022 duur 77.0044ms
maxEvenConjunction resultaat: 1022 duur 111.0063ms
maxEvenConjunction2 resultaat: 1022 duur 81.0047ms

maksimum drempel: 2048
maxEvenDividing resultaat: 2046 duur 114.0065ms
maxEvenDividing2 resultaat: 2046 duur 79.0045ms
maxEvenConjunction resultaat: 2046 duur 113.0065ms
maxEvenConjunction2 resultaat: 2046 duur 81.0046ms

maksimum drempel: 4096
maxEvenDividing resultaat: 4094 duur 114.0065ms
maxEvenDividing2 resultaat: 4094 duur 80.0046ms
maxEvenConjunction resultaat: 4094 duur 111.0063ms
maxEvenConjunction2 resultaat: 4094 duur 78.0045ms

maksimum drempel: 8192
maxEvenDividing resultaat: 8190 duur 107.0062ms
maxEvenDividing2 resultaat: 8190 duur 77.0044ms
maxEvenConjunction resultaat: 8190 duur 111.0063ms
maxEvenConjunction2 resultaat: 8190 duur 77.0044ms

maksimum drempel: 16384
maxEvenDividing resultaat: 16382 duur 109.0063ms
maxEvenDividing2 resultaat: 16382 duur 77.0044ms
maxEvenConjunction resultaat: 16382 duur 108.0062ms
maxEvenConjunction2 resultaat: 16382 duur 77.0044ms

maksimum drempel: 32768
maxEvenDividing resultaat: 32766 duur 112.0064ms
maxEvenDividing2 resultaat: 32766 duur 77.0044ms
maxEvenConjunction resultaat: 32766 duur 109.0062ms
maxEvenConjunction2 resultaat: 32766 duur 78.0045ms

maksimum drempel: 65536
maxEvenDividing resultaat: 65534 duur 109.0062ms
maxEvenDividing2 resultaat: 65534 duur 75.0043ms
maxEvenConjunction resultaat: 65534 duur 109.0063ms
maxEvenConjunction2 resultaat: 65534 duur 79.0045ms

maksimum drempel: 131072
maxEvenDividing resultaat: 131070 duur 108.0061ms
maxEvenDividing2 resultaat: 131070 duur 76.0044ms
maxEvenConjunction resultaat: 131070 duur 110.0063ms
maxEvenConjunction2 resultaat: 131070 duur 80.0046ms

maksimum drempel: 262144
maxEvenDividing resultaat: 262142 duur 110.0063ms
maxEvenDividing2 resultaat: 262142 duur 76.0044ms
maxEvenConjunction resultaat: 262142 duur 107.0061ms
maxEvenConjunction2 resultaat: 262142 duur 78.0044ms

maksimum drempel: 524288
maxEvenDividing resultaat: 524286 duur 109.0062ms
maxEvenDividing2 resultaat: 524286 duur 78.0045ms
maxEvenConjunction resultaat: 524286 duur 109.0062ms
maxEvenConjunction2 resultaat: 524286 duur 80.0046ms

maksimum drempel: 1048576
maxEvenDividing resultaat: 1048574 duur 109.0063ms
maxEvenDividing2 resultaat: 1048574 duur 80.0045ms
maxEvenConjunction resultaat: 1048574 duur 114.0066ms
maxEvenConjunction2 resultaat: 1048574 duur 78.0044ms

maksimum drempel: 2097152
maxEvenDividing resultaat: 2097150 duur 111.0064ms
maxEvenDividing2 resultaat: 2097150 duur 79.0045ms
maxEvenConjunction resultaat: 2097150 duur 112.0064ms
maxEvenConjunction2 resultaat: 2097150 duur 77.0044ms

maksimum drempel: 4194304
maxEvenDividing resultaat: 4194302 duur 111.0063ms
maxEvenDividing2 resultaat: 4194302 duur 78.0045ms
maxEvenConjunction resultaat: 4194302 duur 111.0063ms
maxEvenConjunction2 resultaat: 4194302 duur 77.0044ms

maksimum drempel: 8388608
maxEvenDividing resultaat: 8388606 duur 109.0062ms
maxEvenDividing2 resultaat: 8388606 duur 78.0045ms
maxEvenConjunction resultaat: 8388606 duur 114.0065ms
maxEvenConjunction2 resultaat: 8388606 duur 78.0045ms

maksimum drempel: 16777216
maxEvenDividing resultaat: 16777214 duur 109.0062ms
maxEvenDividing2 resultaat: 16777214 duur 77.0044ms
maxEvenConjunction resultaat: 16777214 duur 109.0063ms
maxEvenConjunction2 resultaat: 16777214 duur 77.0044ms

maksimum drempel: 33554432
maxEvenDividing resultaat: 33554430 duur 113.0065ms
maxEvenDividing2 resultaat: 33554430 duur 78.0045ms
maxEvenConjunction resultaat: 33554430 duur 110.0063ms
maxEvenConjunction2 resultaat: 33554430 duur 80.0045ms

maksimum drempel: 67108864
maxEvenDividing resultaat: 67108860 duur 112.0064ms
maxEvenDividing2 resultaat: 67108860 duur 77.0044ms
maxEvenConjunction resultaat: 67108860 duur 112.0064ms
maxEvenConjunction2 resultaat: 67108860 duur 80.0046ms

maksimum drempel: 134217728
maxEvenDividing resultaat: 134217726 duur 109.0063ms
maxEvenDividing2 resultaat: 134217726 duur 78.0044ms
maxEvenConjunction resultaat: 134217726 duur 114.0065ms
maxEvenConjunction2 resultaat: 134217726 duur 81.0047ms

maksimum drempel: 268435456
maxEvenDividing resultaat: 268435446 duur 111.0064ms
maxEvenDividing2 resultaat: 268435446 duur 79.0045ms
maxEvenConjunction resultaat: 268435446 duur 114.0065ms
maxEvenConjunction2 resultaat: 268435446 duur 79.0045ms

maksimum drempel: 536870912
maxEvenDividing resultaat: 536870910 duur 107.0062ms
maxEvenDividing2 resultaat: 536870910 duur 76.0043ms
maxEvenConjunction resultaat: 536870910 duur 109.0062ms
maxEvenConjunction2 resultaat: 536870910 duur 80.0046ms

Ek kon nie 'n duidelike verduideliking vind waarom die Go-samesteller nie die kode optimaliseer nie en altyd die tweede toestand nagaan, selfs al is die eerste een onwaar. Of is my oΓ« dalk net vaag en sien ek geen ooglopende fout nie? Of moet jy spesiale instruksies aan die samesteller verskaf? Ek sal bly wees vir sinvolle kommentaar.

PS: Ja, net vir die pret het ek soortgelyke toetse op Java 5 en Java 7/8 uitgevoer - alles is duidelik, die uitvoeringstyd is dieselfde.

Bron: will.com

Voeg 'n opmerking