கோவில் உள்ள நிலைமைகள் மற்றும் அவற்றின் வினோதங்கள்

லூப்பில் உள்ள சோதனை நிலைமைகளுக்கான இந்த இரண்டு விருப்பங்களும் செயல்திறனில் சமமானவை என்று நீங்கள் நினைக்கிறீர்களா?

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


இது அனைத்தும் "மூளை வார்ம்-அப்" மூலம் தொடங்கியது; முழு எண்களின் வரிசையில் மிகப்பெரிய இரட்டை எண்ணுக்கான உகந்த தேடலின் உதாரணத்தை நான் கொடுக்க வேண்டியிருந்தது [-x....x]. எண் சமமாக உள்ளதா இல்லையா என்பதைக் கண்டறிய 1 ஆல் தருக்கப் பெருக்கத்தைப் பயன்படுத்தினால், செயல்திறன் எவ்வளவு சிறப்பாக இருக்கும் என்று நான் யோசித்துக்கொண்டிருந்தேன்.


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

Go இல் எனது நிரலாக்க அனுபவம் மிகவும் விரிவானது அல்ல, ஒன்றரை ஆண்டுகளுக்கும் மேலாக, நான் அதை அடிக்கடி பயன்படுத்தினேன், ஆனால் முற்றிலும் பயன்பாட்டு நோக்கங்களுக்காக (நன்றாக, அதிக சுமை http சேவை தொடர்பான ஒரு திட்டத்தைத் தவிர), அதனால் நான் அதனுடன் தொடங்கியது. GoLand ஐ திறந்து ஒரு எளிய தேர்வை எழுதவும்


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
}

அதிக வாசல், செயல்திறனில் அடிக்கடி ஏற்ற இறக்கங்கள் தோன்றும் என்பதைக் காட்டும் முடிவைப் பெறுகிறோம்.

ஒப்பிடுmax 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

இந்த விஷயத்தில், வெவ்வேறு வரம்புகளுக்கு, எங்களிடம் வெவ்வேறு சோதனை தரவு உள்ளது என்பது தெளிவாகிறது, செயலி சுமை (எனது i5-2540M லேப்டாப்பில்) சுமார் 20..30% மாறுபடும், GoLand இலிருந்து இயங்கும் பயன்பாடு ஆக்கிரமித்துள்ள நினைவகம் சராசரியாக உள்ளது. சுமார் 813MB - இது முடிவின் நம்பகத்தன்மையையும் பாதிக்கிறது, நீங்கள் சோதனை நிகழ்வுகளை வட்டில் சேமிக்க வேண்டும் மற்றும் ஒவ்வொரு நுழைவாயிலுக்கான அனைத்து சோதனைகளையும் ஒருவருக்கொருவர் தனிமையில் இயக்க வேண்டும்.

இப்போது, ​​​​இதையெல்லாம் குறைந்த செலவில் எவ்வாறு செயல்படுத்துவது என்று யோசித்து, நிலை சரிபார்ப்பை தானாகவே சரிசெய்கிறேன்

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

மீது

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

நான் மீண்டும் சோதனைகளை நடத்துகிறேன்... எதையும் புரிந்து கொள்வதை நிறுத்துகிறேன் :)

செயல்படுத்தும் நேரம், ஒரு சதவீதத்தின் சதவீதம்/பின்னங்கள் ஆகியவற்றால் வேறுபடாது, ஆனால் 10..15%. நான் விரைவாக மேலும் 2 சோதனைகளைச் சேர்க்கிறேன்:

		
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
}

நான் அதை இயக்கி இந்த படத்தைப் பெறுகிறேன்:ஆரம்ப வரிசை திறன்: 100000000

அதிகபட்ச வரம்பு: 128
maxEvenDividing முடிவு: 126 கால அளவு 116.0066ms
maxEvenDividing2 முடிவு: 126 கால அளவு 79.0045ms
maxEvenConjunction முடிவு: 126 கால அளவு 114.0065ms
maxEvenConjunction2 முடிவு: 126 கால அளவு 83.0048ms

அதிகபட்ச வரம்பு: 256
maxEvenDividing முடிவு: 254 கால அளவு 111.0063ms
maxEvenDividing2 முடிவு: 254 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 254 கால அளவு 110.0063ms
maxEvenConjunction2 முடிவு: 254 கால அளவு 80.0046ms

அதிகபட்ச வரம்பு: 512
maxEvenDividing முடிவு: 510 கால அளவு 114.0066ms
maxEvenDividing2 முடிவு: 510 கால அளவு 80.0045ms
maxEvenConjunction முடிவு: 510 கால அளவு 110.0063ms
maxEvenConjunction2 முடிவு: 510 கால அளவு 80.0046ms

அதிகபட்ச வரம்பு: 1024
maxEvenDividing முடிவு: 1022 கால அளவு 109.0063ms
maxEvenDividing2 முடிவு: 1022 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 1022 கால அளவு 111.0063ms
maxEvenConjunction2 முடிவு: 1022 கால அளவு 81.0047ms

அதிகபட்ச வரம்பு: 2048
maxEvenDividing முடிவு: 2046 கால அளவு 114.0065ms
maxEvenDividing2 முடிவு: 2046 கால அளவு 79.0045ms
maxEvenConjunction முடிவு: 2046 கால அளவு 113.0065ms
maxEvenConjunction2 முடிவு: 2046 கால அளவு 81.0046ms

அதிகபட்ச வரம்பு: 4096
maxEvenDividing முடிவு: 4094 கால அளவு 114.0065ms
maxEvenDividing2 முடிவு: 4094 கால அளவு 80.0046ms
maxEvenConjunction முடிவு: 4094 கால அளவு 111.0063ms
maxEvenConjunction2 முடிவு: 4094 கால அளவு 78.0045ms

அதிகபட்ச வரம்பு: 8192
maxEvenDividing முடிவு: 8190 கால அளவு 107.0062ms
maxEvenDividing2 முடிவு: 8190 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 8190 கால அளவு 111.0063ms
maxEvenConjunction2 முடிவு: 8190 கால அளவு 77.0044ms

அதிகபட்ச வரம்பு: 16384
maxEvenDividing முடிவு: 16382 கால அளவு 109.0063ms
maxEvenDividing2 முடிவு: 16382 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 16382 கால அளவு 108.0062ms
maxEvenConjunction2 முடிவு: 16382 கால அளவு 77.0044ms

அதிகபட்ச வரம்பு: 32768
maxEvenDividing முடிவு: 32766 கால அளவு 112.0064ms
maxEvenDividing2 முடிவு: 32766 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 32766 கால அளவு 109.0062ms
maxEvenConjunction2 முடிவு: 32766 கால அளவு 78.0045ms

அதிகபட்ச வரம்பு: 65536
maxEvenDividing முடிவு: 65534 கால அளவு 109.0062ms
maxEvenDividing2 முடிவு: 65534 கால அளவு 75.0043ms
maxEvenConjunction முடிவு: 65534 கால அளவு 109.0063ms
maxEvenConjunction2 முடிவு: 65534 கால அளவு 79.0045ms

அதிகபட்ச வரம்பு: 131072
maxEvenDividing முடிவு: 131070 கால அளவு 108.0061ms
maxEvenDividing2 முடிவு: 131070 கால அளவு 76.0044ms
maxEvenConjunction முடிவு: 131070 கால அளவு 110.0063ms
maxEvenConjunction2 முடிவு: 131070 கால அளவு 80.0046ms

அதிகபட்ச வரம்பு: 262144
maxEvenDividing முடிவு: 262142 கால அளவு 110.0063ms
maxEvenDividing2 முடிவு: 262142 கால அளவு 76.0044ms
maxEvenConjunction முடிவு: 262142 கால அளவு 107.0061ms
maxEvenConjunction2 முடிவு: 262142 கால அளவு 78.0044ms

அதிகபட்ச வரம்பு: 524288
maxEvenDividing முடிவு: 524286 கால அளவு 109.0062ms
maxEvenDividing2 முடிவு: 524286 கால அளவு 78.0045ms
maxEvenConjunction முடிவு: 524286 கால அளவு 109.0062ms
maxEvenConjunction2 முடிவு: 524286 கால அளவு 80.0046ms

அதிகபட்ச வரம்பு: 1048576
maxEvenDividing முடிவு: 1048574 கால அளவு 109.0063ms
maxEvenDividing2 முடிவு: 1048574 கால அளவு 80.0045ms
maxEvenConjunction முடிவு: 1048574 கால அளவு 114.0066ms
maxEvenConjunction2 முடிவு: 1048574 கால அளவு 78.0044ms

அதிகபட்ச வரம்பு: 2097152
maxEvenDividing முடிவு: 2097150 கால அளவு 111.0064ms
maxEvenDividing2 முடிவு: 2097150 கால அளவு 79.0045ms
maxEvenConjunction முடிவு: 2097150 கால அளவு 112.0064ms
maxEvenConjunction2 முடிவு: 2097150 கால அளவு 77.0044ms

அதிகபட்ச வரம்பு: 4194304
maxEvenDividing முடிவு: 4194302 கால அளவு 111.0063ms
maxEvenDividing2 முடிவு: 4194302 கால அளவு 78.0045ms
maxEvenConjunction முடிவு: 4194302 கால அளவு 111.0063ms
maxEvenConjunction2 முடிவு: 4194302 கால அளவு 77.0044ms

அதிகபட்ச வரம்பு: 8388608
maxEvenDividing முடிவு: 8388606 கால அளவு 109.0062ms
maxEvenDividing2 முடிவு: 8388606 கால அளவு 78.0045ms
maxEvenConjunction முடிவு: 8388606 கால அளவு 114.0065ms
maxEvenConjunction2 முடிவு: 8388606 கால அளவு 78.0045ms

அதிகபட்ச வரம்பு: 16777216
maxEvenDividing முடிவு: 16777214 கால அளவு 109.0062ms
maxEvenDividing2 முடிவு: 16777214 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 16777214 கால அளவு 109.0063ms
maxEvenConjunction2 முடிவு: 16777214 கால அளவு 77.0044ms

அதிகபட்ச வரம்பு: 33554432
maxEvenDividing முடிவு: 33554430 கால அளவு 113.0065ms
maxEvenDividing2 முடிவு: 33554430 கால அளவு 78.0045ms
maxEvenConjunction முடிவு: 33554430 கால அளவு 110.0063ms
maxEvenConjunction2 முடிவு: 33554430 கால அளவு 80.0045ms

அதிகபட்ச வரம்பு: 67108864
maxEvenDividing முடிவு: 67108860 கால அளவு 112.0064ms
maxEvenDividing2 முடிவு: 67108860 கால அளவு 77.0044ms
maxEvenConjunction முடிவு: 67108860 கால அளவு 112.0064ms
maxEvenConjunction2 முடிவு: 67108860 கால அளவு 80.0046ms

அதிகபட்ச வரம்பு: 134217728
maxEvenDividing முடிவு: 134217726 கால அளவு 109.0063ms
maxEvenDividing2 முடிவு: 134217726 கால அளவு 78.0044ms
maxEvenConjunction முடிவு: 134217726 கால அளவு 114.0065ms
maxEvenConjunction2 முடிவு: 134217726 கால அளவு 81.0047ms

அதிகபட்ச வரம்பு: 268435456
maxEvenDividing முடிவு: 268435446 கால அளவு 111.0064ms
maxEvenDividing2 முடிவு: 268435446 கால அளவு 79.0045ms
maxEvenConjunction முடிவு: 268435446 கால அளவு 114.0065ms
maxEvenConjunction2 முடிவு: 268435446 கால அளவு 79.0045ms

அதிகபட்ச வரம்பு: 536870912
maxEvenDividing முடிவு: 536870910 கால அளவு 107.0062ms
maxEvenDividing2 முடிவு: 536870910 கால அளவு 76.0043ms
maxEvenConjunction முடிவு: 536870910 கால அளவு 109.0062ms
maxEvenConjunction2 முடிவு: 536870910 கால அளவு 80.0046ms

கோ கம்பைலர் ஏன் குறியீட்டை மேம்படுத்தவில்லை மற்றும் முதல் நிபந்தனை தவறானதாக இருந்தாலும், இரண்டாவது நிபந்தனையை எப்போதும் சரிபார்க்கிறது என்பதற்கான தெளிவான விளக்கத்தை என்னால் கண்டுபிடிக்க முடியவில்லை. அல்லது ஒருவேளை என் கண்கள் மங்கலாகி இருக்கலாம் மற்றும் நான் எந்த வெளிப்படையான தவறையும் காணவில்லையா? அல்லது கம்பைலருக்கு சில சிறப்பு வழிமுறைகளை வழங்க வேண்டுமா? விவேகமான கருத்துக்களுக்கு நான் மகிழ்ச்சியடைவேன்.

சோசலிஸ்ட் கட்சி: ஆம், வேடிக்கைக்காக, ஜாவா 5 மற்றும் ஜாவா 7/8 இல் இதே போன்ற சோதனைகளை நடத்தினேன் - எல்லாம் தெளிவாக உள்ளது, செயல்படுத்தும் நேரம் ஒரே மாதிரியாக உள்ளது.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்