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

Kiwango cha juu: 16384
maxEvenTokeo la kugawanya: muda wa 16382 115.0066ms
maxEvenTokeo la muunganisho: muda wa 16382 111.0064ms

......

Kiwango cha juu: 8388608
maxEvenTokeo la kugawanya: muda wa 8388606 109.0063ms
maxEvenTokeo la muunganisho: muda wa 8388606 109.0062ms

Kiwango cha juu: 16777216
maxEvenTokeo la kugawanya: muda wa 16777214 108.0062ms
maxEvenTokeo la muunganisho: muda wa 16777214 109.0062ms

Kiwango cha juu: 33554432
maxEvenTokeo la kugawanya: muda wa 33554430 114.0066ms
maxEvenTokeo la muunganisho: muda wa 33554430 110.0063ms

Kiwango cha juu: 67108864
maxEvenTokeo la kugawanya: muda wa 67108860 111.0064ms
maxEvenTokeo la muunganisho: muda wa 67108860 109.0062ms

Kiwango cha juu: 134217728
maxEvenTokeo la kugawanya: muda wa 134217726 108.0062ms
maxEvenTokeo la muunganisho: muda wa 134217726 109.0063ms

Kiwango cha juu: 268435456
maxEvenTokeo la kugawanya: muda wa 268435446 111.0063ms
maxEvenTokeo la muunganisho: muda wa 268435446 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

Nunua upangishaji wa kuaminika wa tovuti zilizo na ulinzi wa DDoS, seva za VPS VDS 🔥 Nunua upangishaji wa tovuti unaoaminika kwa ulinzi wa DDoS, seva za VPS VDS | ProHoster