Go හි කොන්දේසි සහ ඒවායේ විචක්ෂණ

ලූපයක් තුළ තත්ත්ව පරීක්ෂා කිරීම සඳහා මෙම විකල්ප දෙක කාර්ය සාධනයට සමාන යැයි ඔබ සිතනවාද?

		
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
}

එළිපත්ත වැඩි වන තරමට කාර්ය සාධනයේ උච්චාවචනයන් බොහෝ විට පෙනෙන බව පෙන්වන ප්‍රති 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

Go compiler එක කේතය ප්‍රශස්ත නොකරන්නේ ඇයිද යන්න සහ පළමු එක අසත්‍ය වුවද, සෑම විටම දෙවන කොන්දේසිය පරීක්ෂා කරන්නේ මන්දැයි මට පැහැදිලි පැහැදිලි කිරීමක් සොයාගත නොහැකි විය. නැත්නම් සමහර විට මගේ ඇස් බොඳ වී ඇති අතර මට පැහැදිලි වැරැද්දක් නොපෙනේද? නැතහොත් සම්පාදකයට විශේෂ උපදෙස් කිහිපයක් ලබා දීමට ඔබට අවශ්‍යද? සංවේදී අදහස් සඳහා මම සතුටු වෙමි.

PS: ඔව්, හුදෙක් විනෝදය සඳහා, මම Java 5 සහ Java 7/8 මත සමාන පරීක්ෂණ පවත්වා ඇත - සියල්ල පැහැදිලිය, ක්රියාත්මක කිරීමේ කාලය සමාන වේ.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න