Masharti katika Go na ustaarabu wao

Je, unadhani chaguo hizi mbili za hali ya majaribio ndani ya kitanzi ni sawa katika utendaji?

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


Yote ilianza na "uboreshaji wa ubongo"; ilibidi nitoe mfano wa utaftaji bora wa nambari kubwa zaidi katika safu kamili ya nambari [-x....x]. Nilikuwa nikishangaa utendakazi bora zaidi ikiwa ningetumia kuzidisha kimantiki na 1 ili kujua ikiwa nambari ni sawa au la.


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

Uzoefu wangu wa programu katika Go sio mkubwa sana, zaidi ya mwaka mmoja na nusu, niliitumia, ingawa mara nyingi, lakini kwa madhumuni ya matumizi (vizuri, labda isipokuwa kwa mradi mmoja unaohusiana na huduma ya mzigo wa juu wa http), kwa hivyo mimi. alianza nayo. Fungua GoLand na uandike jaribio rahisi


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
}

Tunapata matokeo ambayo yanaonyesha kuwa kizingiti cha juu, mabadiliko ya mara kwa mara katika utendaji yanaonekana.

Linganishamax 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

Ni wazi kuwa katika kesi hii, kwa vizingiti tofauti tuna seti tofauti za data ya majaribio, mzigo wa processor (kwenye kompyuta yangu ya mbali ya i5-2540M) inatofautiana karibu 20..30%, kumbukumbu iliyochukuliwa na programu inayoendesha kutoka GoLand ni wastani. kuhusu 813MB - hii pia huathiri kuegemea kwa matokeo, unahitaji kuokoa kesi za mtihani kwenye diski na kukimbia vipimo vyote kwa kila kizingiti kwa kutengwa kutoka kwa kila mmoja.

Na sasa, nikifikiria jinsi ya kutekeleza haya yote kwa gharama ndogo, mimi hurekebisha moja kwa moja ukaguzi wa hali

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

juu ya

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

Ninaendesha vipimo tena ... na ninaacha kuelewa chochote :)

Muda uliotumika kwenye utekelezaji huanza kutofautiana tena kwa asilimia/visehemu vya asilimia, lakini kwa asilimia 10..15. Ninaongeza haraka majaribio 2 zaidi:

		
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
}

Ninaiendesha na kupata picha hii:uwezo wa safu ya awali: 100000000

Kiwango cha juu: 128
maxEvenTokeo la kugawanya: muda wa 126 116.0066ms
matokeo ya maxEvenDividing2: muda wa 126 79.0045ms
maxEvenTokeo la muunganisho: muda wa 126 114.0065ms
matokeo ya maxEvenConjunction2: muda wa 126 83.0048ms

Kiwango cha juu: 256
maxEvenTokeo la kugawanya: muda wa 254 111.0063ms
matokeo ya maxEvenDividing2: muda wa 254 77.0044ms
maxEvenTokeo la muunganisho: muda wa 254 110.0063ms
matokeo ya maxEvenConjunction2: muda wa 254 80.0046ms

Kiwango cha juu: 512
maxEvenTokeo la kugawanya: muda wa 510 114.0066ms
matokeo ya maxEvenDividing2: muda wa 510 80.0045ms
maxEvenTokeo la muunganisho: muda wa 510 110.0063ms
matokeo ya maxEvenConjunction2: muda wa 510 80.0046ms

Kiwango cha juu: 1024
maxEvenTokeo la kugawanya: muda wa 1022 109.0063ms
matokeo ya maxEvenDividing2: muda wa 1022 77.0044ms
maxEvenTokeo la muunganisho: muda wa 1022 111.0063ms
matokeo ya maxEvenConjunction2: muda wa 1022 81.0047ms

Kiwango cha juu: 2048
maxEvenTokeo la kugawanya: muda wa 2046 114.0065ms
matokeo ya maxEvenDividing2: muda wa 2046 79.0045ms
maxEvenTokeo la muunganisho: muda wa 2046 113.0065ms
matokeo ya maxEvenConjunction2: muda wa 2046 81.0046ms

Kiwango cha juu: 4096
maxEvenTokeo la kugawanya: muda wa 4094 114.0065ms
matokeo ya maxEvenDividing2: muda wa 4094 80.0046ms
maxEvenTokeo la muunganisho: muda wa 4094 111.0063ms
matokeo ya maxEvenConjunction2: muda wa 4094 78.0045ms

Kiwango cha juu: 8192
maxEvenTokeo la kugawanya: muda wa 8190 107.0062ms
matokeo ya maxEvenDividing2: muda wa 8190 77.0044ms
maxEvenTokeo la muunganisho: muda wa 8190 111.0063ms
matokeo ya maxEvenConjunction2: muda wa 8190 77.0044ms

Kiwango cha juu: 16384
maxEvenTokeo la kugawanya: muda wa 16382 109.0063ms
matokeo ya maxEvenDividing2: muda wa 16382 77.0044ms
maxEvenTokeo la muunganisho: muda wa 16382 108.0062ms
matokeo ya maxEvenConjunction2: muda wa 16382 77.0044ms

Kiwango cha juu: 32768
maxEvenTokeo la kugawanya: muda wa 32766 112.0064ms
matokeo ya maxEvenDividing2: muda wa 32766 77.0044ms
maxEvenTokeo la muunganisho: muda wa 32766 109.0062ms
matokeo ya maxEvenConjunction2: muda wa 32766 78.0045ms

Kiwango cha juu: 65536
maxEvenTokeo la kugawanya: muda wa 65534 109.0062ms
matokeo ya maxEvenDividing2: muda wa 65534 75.0043ms
maxEvenTokeo la muunganisho: muda wa 65534 109.0063ms
matokeo ya maxEvenConjunction2: muda wa 65534 79.0045ms

Kiwango cha juu: 131072
maxEvenTokeo la kugawanya: muda wa 131070 108.0061ms
matokeo ya maxEvenDividing2: muda wa 131070 76.0044ms
maxEvenTokeo la muunganisho: muda wa 131070 110.0063ms
matokeo ya maxEvenConjunction2: muda wa 131070 80.0046ms

Kiwango cha juu: 262144
maxEvenTokeo la kugawanya: muda wa 262142 110.0063ms
matokeo ya maxEvenDividing2: muda wa 262142 76.0044ms
maxEvenTokeo la muunganisho: muda wa 262142 107.0061ms
matokeo ya maxEvenConjunction2: muda wa 262142 78.0044ms

Kiwango cha juu: 524288
maxEvenTokeo la kugawanya: muda wa 524286 109.0062ms
matokeo ya maxEvenDividing2: muda wa 524286 78.0045ms
maxEvenTokeo la muunganisho: muda wa 524286 109.0062ms
matokeo ya maxEvenConjunction2: muda wa 524286 80.0046ms

Kiwango cha juu: 1048576
maxEvenTokeo la kugawanya: muda wa 1048574 109.0063ms
matokeo ya maxEvenDividing2: muda wa 1048574 80.0045ms
maxEvenTokeo la muunganisho: muda wa 1048574 114.0066ms
matokeo ya maxEvenConjunction2: muda wa 1048574 78.0044ms

Kiwango cha juu: 2097152
maxEvenTokeo la kugawanya: muda wa 2097150 111.0064ms
matokeo ya maxEvenDividing2: muda wa 2097150 79.0045ms
maxEvenTokeo la muunganisho: muda wa 2097150 112.0064ms
matokeo ya maxEvenConjunction2: muda wa 2097150 77.0044ms

Kiwango cha juu: 4194304
maxEvenTokeo la kugawanya: muda wa 4194302 111.0063ms
matokeo ya maxEvenDividing2: muda wa 4194302 78.0045ms
maxEvenTokeo la muunganisho: muda wa 4194302 111.0063ms
matokeo ya maxEvenConjunction2: muda wa 4194302 77.0044ms

Kiwango cha juu: 8388608
maxEvenTokeo la kugawanya: muda wa 8388606 109.0062ms
matokeo ya maxEvenDividing2: muda wa 8388606 78.0045ms
maxEvenTokeo la muunganisho: muda wa 8388606 114.0065ms
matokeo ya maxEvenConjunction2: muda wa 8388606 78.0045ms

Kiwango cha juu: 16777216
maxEvenTokeo la kugawanya: muda wa 16777214 109.0062ms
matokeo ya maxEvenDividing2: muda wa 16777214 77.0044ms
maxEvenTokeo la muunganisho: muda wa 16777214 109.0063ms
matokeo ya maxEvenConjunction2: muda wa 16777214 77.0044ms

Kiwango cha juu: 33554432
maxEvenTokeo la kugawanya: muda wa 33554430 113.0065ms
matokeo ya maxEvenDividing2: muda wa 33554430 78.0045ms
maxEvenTokeo la muunganisho: muda wa 33554430 110.0063ms
matokeo ya maxEvenConjunction2: muda wa 33554430 80.0045ms

Kiwango cha juu: 67108864
maxEvenTokeo la kugawanya: muda wa 67108860 112.0064ms
matokeo ya maxEvenDividing2: muda wa 67108860 77.0044ms
maxEvenTokeo la muunganisho: muda wa 67108860 112.0064ms
matokeo ya maxEvenConjunction2: muda wa 67108860 80.0046ms

Kiwango cha juu: 134217728
maxEvenTokeo la kugawanya: muda wa 134217726 109.0063ms
matokeo ya maxEvenDividing2: muda wa 134217726 78.0044ms
maxEvenTokeo la muunganisho: muda wa 134217726 114.0065ms
matokeo ya maxEvenConjunction2: muda wa 134217726 81.0047ms

Kiwango cha juu: 268435456
maxEvenTokeo la kugawanya: muda wa 268435446 111.0064ms
matokeo ya maxEvenDividing2: muda wa 268435446 79.0045ms
maxEvenTokeo la muunganisho: muda wa 268435446 114.0065ms
matokeo ya maxEvenConjunction2: muda wa 268435446 79.0045ms

Kiwango cha juu: 536870912
maxEvenTokeo la kugawanya: muda wa 536870910 107.0062ms
matokeo ya maxEvenDividing2: muda wa 536870910 76.0043ms
maxEvenTokeo la muunganisho: muda wa 536870910 109.0062ms
matokeo ya maxEvenConjunction2: muda wa 536870910 80.0046ms

Sikuweza kupata maelezo wazi kwa nini kikusanyaji cha Go hakiboreshi msimbo na hukagua hali ya pili kila wakati, hata kama ya kwanza ni ya uwongo. Au labda macho yangu ni wazi tu na sioni kosa lolote dhahiri? Au unahitaji kutoa maagizo maalum kwa mkusanyaji? Ningefurahi kwa maoni yenye busara.

PS: Ndio, kwa kufurahisha tu, niliendesha vipimo sawa kwenye Java 5 na Java 7/8 - kila kitu ni wazi, wakati wa utekelezaji ni sawa.

Chanzo: mapenzi.com

Kuongeza maoni