Kahanan ing Go lan quirks sing

Apa sampeyan mikir yen rong pilihan kanggo nguji kahanan ing daur ulang padha karo kinerja?

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


Iku kabeh diwiwiti kanthi "panas otak"; Aku kudu menehi conto panelusuran optimal kanggo nomer genap paling gedhe ing array integer [-x....x]. Aku kepingin weruh carane kinerja luwih apik yen aku nggunakake pingan logis dening 1 kanggo tokoh metu apa nomer malah utawa ora.


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

Pengalaman pemrograman ing Go ora akeh banget, mung luwih saka setengah taun, aku nggunakake, sanajan asring, nanging mung kanggo tujuan utilitarian (bisa uga, kajaba kanggo siji proyek sing ana gandhengane karo layanan http kanthi beban dhuwur), mula aku diwiwiti karo. Bukak GoLand lan tulis tes prasaja


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
}

Kita entuk asil sing nuduhake yen ambang sing luwih dhuwur, luwih asring fluktuasi kinerja katon.

Bandhingakemax 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

Cetha yen ing kasus iki, kanggo ambang beda kita duwe set data test sing beda, beban prosesor (ing laptop i5-2540M) beda-beda ing sekitar 20..30%, memori sing dikuwasani dening aplikasi sing mlaku saka GoLand rata-rata. bab 813MB - iki uga mengaruhi linuwih saka asil, sampeyan kudu nyimpen kasus test ing disk lan mbukak kabeh tes kanggo saben batesan ing isolasi saka saben liyane.

Lan saiki, mikir babagan carane ngetrapake kabeh iki kanthi biaya minimal, aku kanthi otomatis mbenerake mriksa kondisi kasebut

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

ing

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

Aku mbukak tes maneh ... lan aku ora ngerti apa-apa :)

Wektu sing ditindakake kanggo eksekusi wiwit ora beda-beda maneh kanthi persentase / pecahan persen, nanging kanthi 10..15%.Aku cepet nambah 2 tes maneh:

		
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
}

Aku mbukak lan njupuk gambar iki:kapasitas array dhisikan: 100000000

ambang maksimum: 128
asil maxEvenDividing: 126 durasi 116.0066ms
asil maxEvenDividing2: 126 durasi 79.0045ms
asil maxEvenConjunction: 126 durasi 114.0065ms
asil maxEvenConjunction2: 126 durasi 83.0048ms

ambang maksimum: 256
asil maxEvenDividing: 254 durasi 111.0063ms
asil maxEvenDividing2: 254 durasi 77.0044ms
asil maxEvenConjunction: 254 durasi 110.0063ms
asil maxEvenConjunction2: 254 durasi 80.0046ms

ambang maksimum: 512
asil maxEvenDividing: 510 durasi 114.0066ms
asil maxEvenDividing2: 510 durasi 80.0045ms
asil maxEvenConjunction: 510 durasi 110.0063ms
asil maxEvenConjunction2: 510 durasi 80.0046ms

ambang maksimum: 1024
asil maxEvenDividing: 1022 durasi 109.0063ms
asil maxEvenDividing2: 1022 durasi 77.0044ms
asil maxEvenConjunction: 1022 durasi 111.0063ms
asil maxEvenConjunction2: 1022 durasi 81.0047ms

ambang maksimum: 2048
asil maxEvenDividing: 2046 durasi 114.0065ms
asil maxEvenDividing2: 2046 durasi 79.0045ms
asil maxEvenConjunction: 2046 durasi 113.0065ms
asil maxEvenConjunction2: 2046 durasi 81.0046ms

ambang maksimum: 4096
asil maxEvenDividing: 4094 durasi 114.0065ms
asil maxEvenDividing2: 4094 durasi 80.0046ms
asil maxEvenConjunction: 4094 durasi 111.0063ms
asil maxEvenConjunction2: 4094 durasi 78.0045ms

ambang maksimum: 8192
asil maxEvenDividing: 8190 durasi 107.0062ms
asil maxEvenDividing2: 8190 durasi 77.0044ms
asil maxEvenConjunction: 8190 durasi 111.0063ms
asil maxEvenConjunction2: 8190 durasi 77.0044ms

ambang maksimum: 16384
asil maxEvenDividing: 16382 durasi 109.0063ms
asil maxEvenDividing2: 16382 durasi 77.0044ms
asil maxEvenConjunction: 16382 durasi 108.0062ms
asil maxEvenConjunction2: 16382 durasi 77.0044ms

ambang maksimum: 32768
asil maxEvenDividing: 32766 durasi 112.0064ms
asil maxEvenDividing2: 32766 durasi 77.0044ms
asil maxEvenConjunction: 32766 durasi 109.0062ms
asil maxEvenConjunction2: 32766 durasi 78.0045ms

ambang maksimum: 65536
asil maxEvenDividing: 65534 durasi 109.0062ms
asil maxEvenDividing2: 65534 durasi 75.0043ms
asil maxEvenConjunction: 65534 durasi 109.0063ms
asil maxEvenConjunction2: 65534 durasi 79.0045ms

ambang maksimum: 131072
asil maxEvenDividing: 131070 durasi 108.0061ms
asil maxEvenDividing2: 131070 durasi 76.0044ms
asil maxEvenConjunction: 131070 durasi 110.0063ms
asil maxEvenConjunction2: 131070 durasi 80.0046ms

ambang maksimum: 262144
asil maxEvenDividing: 262142 durasi 110.0063ms
asil maxEvenDividing2: 262142 durasi 76.0044ms
asil maxEvenConjunction: 262142 durasi 107.0061ms
asil maxEvenConjunction2: 262142 durasi 78.0044ms

ambang maksimum: 524288
asil maxEvenDividing: 524286 durasi 109.0062ms
asil maxEvenDividing2: 524286 durasi 78.0045ms
asil maxEvenConjunction: 524286 durasi 109.0062ms
asil maxEvenConjunction2: 524286 durasi 80.0046ms

ambang maksimum: 1048576
asil maxEvenDividing: 1048574 durasi 109.0063ms
asil maxEvenDividing2: 1048574 durasi 80.0045ms
asil maxEvenConjunction: 1048574 durasi 114.0066ms
asil maxEvenConjunction2: 1048574 durasi 78.0044ms

ambang maksimum: 2097152
asil maxEvenDividing: 2097150 durasi 111.0064ms
asil maxEvenDividing2: 2097150 durasi 79.0045ms
asil maxEvenConjunction: 2097150 durasi 112.0064ms
asil maxEvenConjunction2: 2097150 durasi 77.0044ms

ambang maksimum: 4194304
asil maxEvenDividing: 4194302 durasi 111.0063ms
asil maxEvenDividing2: 4194302 durasi 78.0045ms
asil maxEvenConjunction: 4194302 durasi 111.0063ms
asil maxEvenConjunction2: 4194302 durasi 77.0044ms

ambang maksimum: 8388608
asil maxEvenDividing: 8388606 durasi 109.0062ms
asil maxEvenDividing2: 8388606 durasi 78.0045ms
asil maxEvenConjunction: 8388606 durasi 114.0065ms
asil maxEvenConjunction2: 8388606 durasi 78.0045ms

ambang maksimum: 16777216
asil maxEvenDividing: 16777214 durasi 109.0062ms
asil maxEvenDividing2: 16777214 durasi 77.0044ms
asil maxEvenConjunction: 16777214 durasi 109.0063ms
asil maxEvenConjunction2: 16777214 durasi 77.0044ms

ambang maksimum: 33554432
asil maxEvenDividing: 33554430 durasi 113.0065ms
asil maxEvenDividing2: 33554430 durasi 78.0045ms
asil maxEvenConjunction: 33554430 durasi 110.0063ms
asil maxEvenConjunction2: 33554430 durasi 80.0045ms

ambang maksimum: 67108864
asil maxEvenDividing: 67108860 durasi 112.0064ms
asil maxEvenDividing2: 67108860 durasi 77.0044ms
asil maxEvenConjunction: 67108860 durasi 112.0064ms
asil maxEvenConjunction2: 67108860 durasi 80.0046ms

ambang maksimum: 134217728
asil maxEvenDividing: 134217726 durasi 109.0063ms
asil maxEvenDividing2: 134217726 durasi 78.0044ms
asil maxEvenConjunction: 134217726 durasi 114.0065ms
asil maxEvenConjunction2: 134217726 durasi 81.0047ms

ambang maksimum: 268435456
asil maxEvenDividing: 268435446 durasi 111.0064ms
asil maxEvenDividing2: 268435446 durasi 79.0045ms
asil maxEvenConjunction: 268435446 durasi 114.0065ms
asil maxEvenConjunction2: 268435446 durasi 79.0045ms

ambang maksimum: 536870912
asil maxEvenDividing: 536870910 durasi 107.0062ms
asil maxEvenDividing2: 536870910 durasi 76.0043ms
asil maxEvenConjunction: 536870910 durasi 109.0062ms
asil maxEvenConjunction2: 536870910 durasi 80.0046ms

Aku ora bisa nemokake panjelasan sing jelas kenapa kompiler Go ora ngoptimalake kode kasebut lan tansah mriksa kondisi kapindho, sanajan sing pisanan palsu. Utawa mungkin mripatku mung surem lan aku ora weruh kesalahan sing jelas? Utawa sampeyan kudu nyedhiyani sawetara instruksi khusus kanggo compiler? Aku bakal bungah kanggo komentar wicaksana.

PS: Ya, mung kanggo seneng-seneng, aku nglakokake tes sing padha ing Java 5 lan Java 7/8 - kabeh wis jelas, wektu eksekusi padha.

Source: www.habr.com

Add a comment