Şert û mercên li Go û hûrgelên wan

Ma hûn difikirin ku ev her du vebijarkên ji bo şert û mercên ceribandinê di hundurê lûkê de di performansê de wekhev in?

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


Hemî bi "germkirina mêjî" dest pê kir; Diviya bû ku min mînakek lêgerînek çêtirîn ji bo jimareya herî mezin di rêzek jimaran de [-x....x] bidim. Ez meraq dikirim ka dê performansa wê çiqas çêtir be heke min pirkirina mentiqî bi 1-ê bi kar bîne da ku ez fêhm bikim ka hejmarek zewac e an na.


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

Tecrûbeya min a bernamesaziyê li Go ne pir berfireh e, tenê ji sal û nîvekê, min ew bikar anî, her çend pir caran, lê bi tenê ji bo mebestên kêrhatî (belkî, belkî ji bilî projeyek ku bi karûbarek http-ya bilind-bar ve girêdayî ye), min bikar anî. pê dest pê kir. GoLand vekin û ceribandinek hêsan binivîsin


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
}

Em encamek werdigirin ku destnîşan dike ku her ku bend bilindtir dibe, pir caran guheztinên performansê xuya dibin.

Mûqayesekirinmax 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

Eşkere ye ku di vê rewşê de, ji bo bendavên cihêreng me komek daneyên ceribandinê yên cihêreng hene, barkirina pêvajoyê (li ser laptopê min i5-2540M) li dora 20..30% diguhere, bîranîna ku ji hêla serîlêdana ku ji GoLand-ê ve tê xebitandin bi navînî ye. bi qasî 813 MB - ev jî bandorê li pêbaweriya encamê dike, hûn hewce ne ku dozên ceribandinê li ser dîskê hilînin û hemî ceribandinan ji bo her astekê ji hev veqetînin.

Û naha, ez difikirim ka meriv çawa van hemîyan bi lêçûnên hindik re bicîh tîne, ez bixweber kontrola şertê rast dikim

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

li ser

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

Ez dîsa testan dimeşînim... û ez ji tiştekî fam nakim :)

Dema ku li ser darvekirinê derbas dibe, êdî ne ji sedî/parçeyên ji sedî, lê bi 10..15% dest pê dike, ez zû 2 ceribandinên din lê zêde dikim:

		
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
}

Ez wê dixebitim û vî wêneyî distînim:kapasîteya array destpêkê: 100000000

sînorê herî zêde: 128
Encama maxEvenDividing: 126 demajoya 116.0066ms
maxEvenDividing2 encam: 126 demajoya 79.0045ms
Encama maxEvenConjunction: 126 demajoya 114.0065ms
maxEvenConjunction2 encam: 126 duration 83.0048ms

sînorê herî zêde: 256
Encama maxEvenDividing: 254 demajoya 111.0063ms
maxEvenDividing2 encam: 254 demajoya 77.0044ms
Encama maxEvenConjunction: 254 demajoya 110.0063ms
maxEvenConjunction2 encam: 254 duration 80.0046ms

sînorê herî zêde: 512
Encama maxEvenDividing: 510 demajoya 114.0066ms
maxEvenDividing2 encam: 510 demajoya 80.0045ms
Encama maxEvenConjunction: 510 demajoya 110.0063ms
maxEvenConjunction2 encam: 510 duration 80.0046ms

sînorê herî zêde: 1024
Encama maxEvenDividing: 1022 demajoya 109.0063ms
maxEvenDividing2 encam: 1022 demajoya 77.0044ms
Encama maxEvenConjunction: 1022 demajoya 111.0063ms
maxEvenConjunction2 encam: 1022 duration 81.0047ms

sînorê herî zêde: 2048
Encama maxEvenDividing: 2046 demajoya 114.0065ms
maxEvenDividing2 encam: 2046 demajoya 79.0045ms
Encama maxEvenConjunction: 2046 demajoya 113.0065ms
maxEvenConjunction2 encam: 2046 duration 81.0046ms

sînorê herî zêde: 4096
Encama maxEvenDividing: 4094 demajoya 114.0065ms
maxEvenDividing2 encam: 4094 demajoya 80.0046ms
Encama maxEvenConjunction: 4094 demajoya 111.0063ms
maxEvenConjunction2 encam: 4094 duration 78.0045ms

sînorê herî zêde: 8192
Encama maxEvenDividing: 8190 demajoya 107.0062ms
maxEvenDividing2 encam: 8190 demajoya 77.0044ms
Encama maxEvenConjunction: 8190 demajoya 111.0063ms
maxEvenConjunction2 encam: 8190 duration 77.0044ms

sînorê herî zêde: 16384
Encama maxEvenDividing: 16382 demajoya 109.0063ms
maxEvenDividing2 encam: 16382 demajoya 77.0044ms
Encama maxEvenConjunction: 16382 demajoya 108.0062ms
maxEvenConjunction2 encam: 16382 duration 77.0044ms

sînorê herî zêde: 32768
Encama maxEvenDividing: 32766 demajoya 112.0064ms
maxEvenDividing2 encam: 32766 demajoya 77.0044ms
Encama maxEvenConjunction: 32766 demajoya 109.0062ms
maxEvenConjunction2 encam: 32766 duration 78.0045ms

sînorê herî zêde: 65536
Encama maxEvenDividing: 65534 demajoya 109.0062ms
maxEvenDividing2 encam: 65534 demajoya 75.0043ms
Encama maxEvenConjunction: 65534 demajoya 109.0063ms
maxEvenConjunction2 encam: 65534 duration 79.0045ms

sînorê herî zêde: 131072
Encama maxEvenDividing: 131070 demajoya 108.0061ms
maxEvenDividing2 encam: 131070 demajoya 76.0044ms
Encama maxEvenConjunction: 131070 demajoya 110.0063ms
maxEvenConjunction2 encam: 131070 duration 80.0046ms

sînorê herî zêde: 262144
Encama maxEvenDividing: 262142 demajoya 110.0063ms
maxEvenDividing2 encam: 262142 demajoya 76.0044ms
Encama maxEvenConjunction: 262142 demajoya 107.0061ms
maxEvenConjunction2 encam: 262142 duration 78.0044ms

sînorê herî zêde: 524288
Encama maxEvenDividing: 524286 demajoya 109.0062ms
maxEvenDividing2 encam: 524286 demajoya 78.0045ms
Encama maxEvenConjunction: 524286 demajoya 109.0062ms
maxEvenConjunction2 encam: 524286 duration 80.0046ms

sînorê herî zêde: 1048576
Encama maxEvenDividing: 1048574 demajoya 109.0063ms
maxEvenDividing2 encam: 1048574 demajoya 80.0045ms
Encama maxEvenConjunction: 1048574 demajoya 114.0066ms
maxEvenConjunction2 encam: 1048574 duration 78.0044ms

sînorê herî zêde: 2097152
Encama maxEvenDividing: 2097150 demajoya 111.0064ms
maxEvenDividing2 encam: 2097150 demajoya 79.0045ms
Encama maxEvenConjunction: 2097150 demajoya 112.0064ms
maxEvenConjunction2 encam: 2097150 duration 77.0044ms

sînorê herî zêde: 4194304
Encama maxEvenDividing: 4194302 demajoya 111.0063ms
maxEvenDividing2 encam: 4194302 demajoya 78.0045ms
Encama maxEvenConjunction: 4194302 demajoya 111.0063ms
maxEvenConjunction2 encam: 4194302 duration 77.0044ms

sînorê herî zêde: 8388608
Encama maxEvenDividing: 8388606 demajoya 109.0062ms
maxEvenDividing2 encam: 8388606 demajoya 78.0045ms
Encama maxEvenConjunction: 8388606 demajoya 114.0065ms
maxEvenConjunction2 encam: 8388606 duration 78.0045ms

sînorê herî zêde: 16777216
Encama maxEvenDividing: 16777214 demajoya 109.0062ms
maxEvenDividing2 encam: 16777214 demajoya 77.0044ms
Encama maxEvenConjunction: 16777214 demajoya 109.0063ms
maxEvenConjunction2 encam: 16777214 duration 77.0044ms

sînorê herî zêde: 33554432
Encama maxEvenDividing: 33554430 demajoya 113.0065ms
maxEvenDividing2 encam: 33554430 demajoya 78.0045ms
Encama maxEvenConjunction: 33554430 demajoya 110.0063ms
maxEvenConjunction2 encam: 33554430 duration 80.0045ms

sînorê herî zêde: 67108864
Encama maxEvenDividing: 67108860 demajoya 112.0064ms
maxEvenDividing2 encam: 67108860 demajoya 77.0044ms
Encama maxEvenConjunction: 67108860 demajoya 112.0064ms
maxEvenConjunction2 encam: 67108860 duration 80.0046ms

sînorê herî zêde: 134217728
Encama maxEvenDividing: 134217726 demajoya 109.0063ms
maxEvenDividing2 encam: 134217726 demajoya 78.0044ms
Encama maxEvenConjunction: 134217726 demajoya 114.0065ms
maxEvenConjunction2 encam: 134217726 duration 81.0047ms

sînorê herî zêde: 268435456
Encama maxEvenDividing: 268435446 demajoya 111.0064ms
maxEvenDividing2 encam: 268435446 demajoya 79.0045ms
Encama maxEvenConjunction: 268435446 demajoya 114.0065ms
maxEvenConjunction2 encam: 268435446 duration 79.0045ms

sînorê herî zêde: 536870912
Encama maxEvenDividing: 536870910 demajoya 107.0062ms
maxEvenDividing2 encam: 536870910 demajoya 76.0043ms
Encama maxEvenConjunction: 536870910 demajoya 109.0062ms
maxEvenConjunction2 encam: 536870910 duration 80.0046ms

Min nikarî ravekirinek zelal bibînim ka çima berhevkarê Go kodê xweşbîn nake û her gav şertê duyemîn kontrol dike, hetta ya yekem xelet be. An jî dibe ku çavên min tenê şîn bin û ez xeletiyek eşkere nabînim? An jî hûn hewce ne ku hin rêwerzên taybetî ji berhevker re peyda bikin? Ez ê ji bo şîroveyên maqûl kêfxweş bibim.

PS: Erê, tenê ji bo kêfê, min ceribandinên bi vî rengî li ser Java 5 û Java 7/8 meşand - her tişt zelal e, dema darvekirinê yek e.

Source: www.habr.com

Add a comment