Ydych chi'n meddwl bod y ddau opsiwn hyn ar gyfer profi amodau y tu mewn i ddolen yn cyfateb o ran perfformiad?
if a > b && c*2 > d {
....
}
// ΠΈ
if a <= b {
continue;
}
if c*2 > d {
....
}
Dechreuodd y cyfan gyda βcynhesu'r ymennyddβ; roedd yn rhaid i mi roi enghraifft o'r chwiliad gorau posibl am yr eilrif mwyaf mewn amrywiaeth o gyfanrifau [-x....x]. Roeddwn yn meddwl tybed faint fyddai perfformiad gwell pe bawn yn defnyddio lluosi rhesymegol ag 1 i ddarganfod a yw rhif yn eilrif ai peidio.
//Ρ ΡΠ΅ΡΠ½ΡΡ
ΡΠΈΡΠ΅Π» ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ Π±ΠΈΡ Π²ΡΠ΅Π³Π΄Π° ΡΠ°Π²Π΅Π½ 0
value & 1 == 0
//vs ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄
value % 2 == 0
Nid yw fy mhrofiad rhaglennu yn Go yn helaeth iawn, ychydig dros flwyddyn a hanner, defnyddiais ef, er yn aml, ond at ddibenion iwtilitaraidd yn unig (wel, efallai heblaw am un prosiect yn ymwneud Γ’ gwasanaeth http llwyth uchel), felly fe wnes i dechrau ag ef. Agor GoLand ac ysgrifennu prawf syml
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
}
Cawn ganlyniad sy'n dangos po uchaf yw'r trothwy, y mwyaf aml y mae amrywiadau mewn perfformiad yn ymddangos.
Cymharwchmax 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
Mae'n amlwg, yn yr achos hwn, ar gyfer gwahanol drothwyon mae gennym setiau gwahanol o ddata prawf, mae llwyth y prosesydd (ar fy ngliniadur i5-2540M) yn amrywio o gwmpas 20..30%, mae'r cof a feddiannir gan y cymhwysiad sy'n rhedeg o GoLand ar gyfartaledd tua 813MB - mae hyn hefyd yn effeithio ar ddibynadwyedd y canlyniad, mae angen i chi arbed achosion prawf ar ddisg a rhedeg yr holl brofion ar gyfer pob trothwy ar wahΓ’n i'w gilydd.
Ac yn awr, gan feddwl am sut i weithredu hyn i gyd heb fawr o gostau, rwy'n cywiro'r gwiriad cyflwr yn awtomatig
if value > current && value&1 == 0 {
current = value
}
ar
if value <= current {
continue;
}
if value&1 == 0 {
current = value
}
Rwy'n rhedeg y profion eto ... a dwi'n stopio deall unrhyw beth :)
Nid yw'r amser a dreulir ar ddienyddio yn dechrau amrywio bellach yn Γ΄l canrannau/ffracsiynau o y cant, ond 10..15% Rwy'n ychwanegu 2 brawf arall yn gyflym:
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
}
Rwy'n ei redeg ac yn cael y llun hwn:capasiti arae cychwynnol: 100000000
trothwy uchaf: 128
maxEvenDividing canlyniad: 126 hyd 116.0066ms
canlyniad maxEvenDividing2: 126 hyd 79.0045ms
maxEvenConjunction canlyniad: 126 hyd 114.0065ms
maxEvenConjunction2 canlyniad: 126 hyd 83.0048ms
trothwy uchaf: 256
maxEvenDividing canlyniad: 254 hyd 111.0063ms
canlyniad maxEvenDividing2: 254 hyd 77.0044ms
maxEvenConjunction canlyniad: 254 hyd 110.0063ms
maxEvenConjunction2 canlyniad: 254 hyd 80.0046ms
trothwy uchaf: 512
maxEvenDividing canlyniad: 510 hyd 114.0066ms
canlyniad maxEvenDividing2: 510 hyd 80.0045ms
maxEvenConjunction canlyniad: 510 hyd 110.0063ms
maxEvenConjunction2 canlyniad: 510 hyd 80.0046ms
trothwy uchaf: 1024
maxEvenDividing canlyniad: 1022 hyd 109.0063ms
canlyniad maxEvenDividing2: 1022 hyd 77.0044ms
maxEvenConjunction canlyniad: 1022 hyd 111.0063ms
maxEvenConjunction2 canlyniad: 1022 hyd 81.0047ms
trothwy uchaf: 2048
maxEvenDividing canlyniad: 2046 hyd 114.0065ms
canlyniad maxEvenDividing2: 2046 hyd 79.0045ms
maxEvenConjunction canlyniad: 2046 hyd 113.0065ms
maxEvenConjunction2 canlyniad: 2046 hyd 81.0046ms
trothwy uchaf: 4096
maxEvenDividing canlyniad: 4094 hyd 114.0065ms
canlyniad maxEvenDividing2: 4094 hyd 80.0046ms
maxEvenConjunction canlyniad: 4094 hyd 111.0063ms
maxEvenConjunction2 canlyniad: 4094 hyd 78.0045ms
trothwy uchaf: 8192
maxEvenDividing canlyniad: 8190 hyd 107.0062ms
canlyniad maxEvenDividing2: 8190 hyd 77.0044ms
maxEvenConjunction canlyniad: 8190 hyd 111.0063ms
maxEvenConjunction2 canlyniad: 8190 hyd 77.0044ms
trothwy uchaf: 16384
maxEvenDividing canlyniad: 16382 hyd 109.0063ms
canlyniad maxEvenDividing2: 16382 hyd 77.0044ms
maxEvenConjunction canlyniad: 16382 hyd 108.0062ms
maxEvenConjunction2 canlyniad: 16382 hyd 77.0044ms
trothwy uchaf: 32768
maxEvenDividing canlyniad: 32766 hyd 112.0064ms
canlyniad maxEvenDividing2: 32766 hyd 77.0044ms
maxEvenConjunction canlyniad: 32766 hyd 109.0062ms
maxEvenConjunction2 canlyniad: 32766 hyd 78.0045ms
trothwy uchaf: 65536
maxEvenDividing canlyniad: 65534 hyd 109.0062ms
canlyniad maxEvenDividing2: 65534 hyd 75.0043ms
maxEvenConjunction canlyniad: 65534 hyd 109.0063ms
maxEvenConjunction2 canlyniad: 65534 hyd 79.0045ms
trothwy uchaf: 131072
maxEvenDividing canlyniad: 131070 hyd 108.0061ms
canlyniad maxEvenDividing2: 131070 hyd 76.0044ms
maxEvenConjunction canlyniad: 131070 hyd 110.0063ms
maxEvenConjunction2 canlyniad: 131070 hyd 80.0046ms
trothwy uchaf: 262144
maxEvenDividing canlyniad: 262142 hyd 110.0063ms
canlyniad maxEvenDividing2: 262142 hyd 76.0044ms
maxEvenConjunction canlyniad: 262142 hyd 107.0061ms
maxEvenConjunction2 canlyniad: 262142 hyd 78.0044ms
trothwy uchaf: 524288
maxEvenDividing canlyniad: 524286 hyd 109.0062ms
canlyniad maxEvenDividing2: 524286 hyd 78.0045ms
maxEvenConjunction canlyniad: 524286 hyd 109.0062ms
maxEvenConjunction2 canlyniad: 524286 hyd 80.0046ms
trothwy uchaf: 1048576
maxEvenDividing canlyniad: 1048574 hyd 109.0063ms
canlyniad maxEvenDividing2: 1048574 hyd 80.0045ms
maxEvenConjunction canlyniad: 1048574 hyd 114.0066ms
maxEvenConjunction2 canlyniad: 1048574 hyd 78.0044ms
trothwy uchaf: 2097152
maxEvenDividing canlyniad: 2097150 hyd 111.0064ms
canlyniad maxEvenDividing2: 2097150 hyd 79.0045ms
maxEvenConjunction canlyniad: 2097150 hyd 112.0064ms
maxEvenConjunction2 canlyniad: 2097150 hyd 77.0044ms
trothwy uchaf: 4194304
maxEvenDividing canlyniad: 4194302 hyd 111.0063ms
canlyniad maxEvenDividing2: 4194302 hyd 78.0045ms
maxEvenConjunction canlyniad: 4194302 hyd 111.0063ms
maxEvenConjunction2 canlyniad: 4194302 hyd 77.0044ms
trothwy uchaf: 8388608
maxEvenDividing canlyniad: 8388606 hyd 109.0062ms
canlyniad maxEvenDividing2: 8388606 hyd 78.0045ms
maxEvenConjunction canlyniad: 8388606 hyd 114.0065ms
maxEvenConjunction2 canlyniad: 8388606 hyd 78.0045ms
trothwy uchaf: 16777216
maxEvenDividing canlyniad: 16777214 hyd 109.0062ms
canlyniad maxEvenDividing2: 16777214 hyd 77.0044ms
maxEvenConjunction canlyniad: 16777214 hyd 109.0063ms
maxEvenConjunction2 canlyniad: 16777214 hyd 77.0044ms
trothwy uchaf: 33554432
maxEvenDividing canlyniad: 33554430 hyd 113.0065ms
canlyniad maxEvenDividing2: 33554430 hyd 78.0045ms
maxEvenConjunction canlyniad: 33554430 hyd 110.0063ms
maxEvenConjunction2 canlyniad: 33554430 hyd 80.0045ms
trothwy uchaf: 67108864
maxEvenDividing canlyniad: 67108860 hyd 112.0064ms
canlyniad maxEvenDividing2: 67108860 hyd 77.0044ms
maxEvenConjunction canlyniad: 67108860 hyd 112.0064ms
maxEvenConjunction2 canlyniad: 67108860 hyd 80.0046ms
trothwy uchaf: 134217728
maxEvenDividing canlyniad: 134217726 hyd 109.0063ms
canlyniad maxEvenDividing2: 134217726 hyd 78.0044ms
maxEvenConjunction canlyniad: 134217726 hyd 114.0065ms
maxEvenConjunction2 canlyniad: 134217726 hyd 81.0047ms
trothwy uchaf: 268435456
maxEvenDividing canlyniad: 268435446 hyd 111.0064ms
canlyniad maxEvenDividing2: 268435446 hyd 79.0045ms
maxEvenConjunction canlyniad: 268435446 hyd 114.0065ms
maxEvenConjunction2 canlyniad: 268435446 hyd 79.0045ms
trothwy uchaf: 536870912
maxEvenDividing canlyniad: 536870910 hyd 107.0062ms
canlyniad maxEvenDividing2: 536870910 hyd 76.0043ms
maxEvenConjunction canlyniad: 536870910 hyd 109.0062ms
maxEvenConjunction2 canlyniad: 536870910 hyd 80.0046ms
Ni allwn ddod o hyd i esboniad clir pam nad yw'r casglwr Go yn gwneud y gorau o'r cod ac yn gwirio'r ail amod bob amser, hyd yn oed os yw'r un cyntaf yn ffug. Neu efallai bod fy llygaid yn aneglur ac nid wyf yn gweld unrhyw gamgymeriad amlwg? Neu a oes angen i chi ddarparu rhai cyfarwyddiadau arbennig i'r casglwr? Byddwn yn falch o gael sylwadau synhwyrol.
PS: Ydw, dim ond am hwyl, cynhaliais brofion tebyg ar Java 5 a Java 7/8 - mae popeth yn glir, mae'r amser gweithredu yr un peth.
Ffynhonnell: hab.com