Você acha que essas duas opções para verificar condições dentro de um loop são equivalentes em desempenho?
if a > b && c*2 > d { .... }
Tudo começou com um "aquecimento para o cérebro", era necessÔrio dar um exemplo de uma pesquisa ideal por uma matriz de números inteiros [-x .... x] para o maior número par. Eu queria saber quanto desempenho seria maior se, para descobrir um número par ou não, usasse a multiplicação lógica por 1.
Minha experiência de programação no Go não é muito grande, apenas um ano e meio, eu a usei, embora com frequência, mas para fins puramente utilitÔrios (bem, talvez exceto por um projeto relacionado a um serviço http altamente carregado), então comecei com ele. Abra o GoLand e escreva um teste simples
package main import ( "fmt" "log" "math" "math/rand" "time" ) const size = 100000000
Obtemos um resultado que mostra que, quanto mais alto o limite, mais frequentemente aparecem flutuaƧƵes em termos de desempenho.
Comparemax 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
à claro que, neste caso, para limites diferentes, temos conjuntos de dados de teste diferentes, a carga do processador (no meu laptop i5-2540M) varia em torno de 20 a 30%, a memória ocupada pelo aplicativo em execução no GoLand é em média de 813 MB - isso também é afeta a confiabilidade do resultado, é necessÔrio implementar a preservação dos conjuntos de testes em disco e executar todos os testes para cada limite isoladamente.
E pensando em como implementar tudo isso a um custo mĆnimo, corrijo automaticamente a verificação da condição
if value > current && value&1 == 0 { current = value }
em
if value <= current { continue; } if value&1 == 0 { current = value }
Eu executo os testes novamente ... e paro de entender algo :)
O tempo gasto na execução não difere mais em porcentagem / fração de porcentagem, mas em 10 a 15% adiciono rapidamente mais 2 testes:
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 }
Eu inicio e recebo esta imagem:capacidade inicial da matriz: 100000000
limite mƔximo: 128
resultado maxEvenDividing: 126 duração 116.0066ms
resultado maxEvenDividing2: 126 duração 79.0045ms
resultado maxEvenConjunction: 126 duração 114.0065ms
resultado maxEvenConjunction2: 126 duração 83.0048ms
limite mƔximo: 256
resultado maxEvenDividing: 254 duração 111.0063ms
resultado maxEvenDividing2: 254 duração 77.0044ms
resultado maxEvenConjunction: 254 duração 110.0063ms
resultado maxEvenConjunction2: 254 duração 80.0046ms
limite mƔximo: 512
resultado maxEvenDividing: 510 duração 114.0066ms
resultado maxEvenDividing2: 510 duração 80.0045ms
resultado maxEvenConjunction: 510 duração 110.0063ms
resultado maxEvenConjunction2: 510 duração 80.0046ms
limite mƔximo: 1024
resultado maxEvenDividing: 1022 duração 109.0063ms
resultado maxEvenDividing2: 1022 duração 77.0044ms
resultado maxEvenConjunction: 1022 duração 111.0063ms
resultado maxEvenConjunction2: 1022 duração 81.0047ms
limite mƔximo: 2048
resultado maxEvenDividing: 2046 duração 114.0065ms
resultado maxEvenDividing2: 2046 duração 79.0045ms
resultado maxEvenConjunction: 2046 duração 113.0065ms
resultado maxEvenConjunction2: 2046 duração 81.0046ms
limite mƔximo: 4096
resultado maxEvenDividing: 4094 duração 114.0065ms
resultado maxEvenDividing2: 4094 duração 80.0046ms
resultado maxEvenConjunction: 4094 duração 111.0063ms
resultado maxEvenConjunction2: 4094 duração 78.0045ms
limite mƔximo: 8192
resultado maxEvenDividing: 8190 duração 107.0062ms
resultado maxEvenDividing2: 8190 duração 77.0044ms
resultado maxEvenConjunction: 8190 duração 111.0063ms
resultado maxEvenConjunction2: 8190 duração 77.0044ms
limite mƔximo: 16384
resultado maxEvenDividing: 16382 duração 109.0063ms
resultado maxEvenDividing2: 16382 duração 77.0044ms
resultado maxEvenConjunction: 16382 duração 108.0062ms
resultado maxEvenConjunction2: 16382 duração 77.0044ms
limite mƔximo: 32768
resultado maxEvenDividing: 32766 duração 112.0064ms
resultado maxEvenDividing2: 32766 duração 77.0044ms
resultado maxEvenConjunction: 32766 duração 109.0062ms
resultado maxEvenConjunction2: 32766 duração 78.0045ms
limite mƔximo: 65536
resultado maxEvenDividing: 65534 duração 109.0062ms
resultado maxEvenDividing2: 65534 duração 75.0043ms
resultado maxEvenConjunction: 65534 duração 109.0063ms
resultado maxEvenConjunction2: 65534 duração 79.0045ms
limite mƔximo: 131072
resultado maxEvenDividing: 131070 duração 108.0061ms
resultado maxEvenDividing2: 131070 duração 76.0044ms
resultado maxEvenConjunction: 131070 duração 110.0063ms
resultado maxEvenConjunction2: 131070 duração 80.0046ms
limite mƔximo: 262144
resultado mÔximo: 262142 duração 110.0063ms
resultado maxEvenDividing2: 262142 duração 76.0044ms
resultado maxEvenConjunction: 262142 duração 107.0061ms
resultado maxEvenConjunction2: 262142 duração 78.0044ms
limite mƔximo: 524288
resultado maxEvenDividing: 524286 duração 109.0062ms
resultado maxEvenDividing2: 524286 duração 78.0045ms
resultado maxEvenConjunction: 524286 duração 109.0062ms
resultado maxEvenConjunction2: 524286 duração 80.0046ms
limite mƔximo: 1048576
resultado maxEvenDividing: 1048574 duração 109.0063ms
resultado maxEvenDividing2: 1048574 duração 80.0045ms
resultado maxEvenConjunction: 1048574 duração 114.0066ms
resultado maxEvenConjunction2: 1048574 duração 78.0044ms
limite mƔximo: 2097152
resultado maxEvenDividing: 2097150 duração 111.0064ms
resultado maxEvenDividing2: 2097150 duração 79.0045ms
resultado maxEvenConjunction: 2097150 duração 112.0064ms
resultado maxEvenConjunction2: 2097150 duração 77.0044ms
limite mƔximo: 4194304
resultado maxEvenDividing: 4194302 duração 111.0063ms
resultado maxEvenDividing2: 4194302 duração 78.0045ms
resultado maxEvenConjunction: 4194302 duração 111.0063ms
resultado maxEvenConjunction2: 4194302 duração 77.0044ms
limite mƔximo: 8388608
resultado mÔximo: 8388606 duração 109.0062ms
resultado maxEvenDividing2: 8388606 duração 78.0045ms
resultado maxEvenConjunction: 8388606 duração 114.0065ms
resultado maxEvenConjunction2: 8388606 duração 78.0045ms
limite mƔximo: 16777216
resultado maxEvenDividing: 16777214 duração 109.0062ms
resultado maxEvenDividing2: 16777214 duração 77.0044ms
resultado maxEvenConjunction: 16777214 duração 109.0063ms
resultado maxEvenConjunction2: 16777214 duração 77.0044ms
limite mƔximo: 33554432
resultado maxEvenDividing: 33554430 duração 113.0065ms
resultado maxEvenDividing2: 33554430 duração 78.0045ms
resultado maxEvenConjunction: 33554430 duração 110.0063ms
resultado maxEvenConjunction2: 33554430 duração 80.0045ms
limite mƔximo: 67108864
resultado maxEvenDividing: 67108860 duração 112.0064ms
resultado maxEvenDividing2: 67108860 duração 77.0044ms
resultado maxEvenConjunction: 67108860 duração 112.0064ms
resultado maxEvenConjunction2: 67108860 duração 80.0046ms
limite mƔximo: 134217728
resultado mÔximo: 134217726 duração 109.0063ms
resultado maxEvenDividing2: 134217726 duração 78.0044ms
resultado maxEvenConjunction: 134217726 duração 114.0065ms
resultado maxEvenConjunction2: 134217726 duração 81.0047ms
limite mƔximo: 268435456
resultado maxEvenDividing: 268435446 duração 111.0064ms
resultado maxEvenDividing2: 268435446 duração 79.0045ms
resultado maxEvenConjunction: 268435446 duração 114.0065ms
resultado maxEvenConjunction2: 268435446 duração 79.0045ms
limite mƔximo: 536870912
resultado maxEvenDividing: 536870910 duração 107.0062ms
resultado maxEvenDividing2: 536870910 duração 76.0043ms
resultado maxEvenConjunction: 536870910 duração 109.0062ms
resultado maxEvenConjunction2: 536870910 duração 80.0046ms
Uma explicação clara de por que o compilador Go não otimiza o código e sempre verifica a segunda condição, mesmo que a primeira seja falsa, não encontrei. Ou talvez meu olho esteja "embaçado" e não vejo nenhum erro óbvio? Ou você precisa especificar algumas instruções especiais para o compilador? Eu ficaria feliz com comentÔrios sensatos.
PS: Sim, por diversão, fiz testes semelhantes no Java 5 e Java 7/8 - tudo estÔ claro, o tempo de execução é o mesmo.