Je veux supprimer certains éléments d'une tranche, et https://github.com/golang/go/wiki/SliceTricks conseille cette tranche de manipulation:golang supprimer des éléments lorsque vous parcourez tranche paniques
a = append(a[:i], a[i+1:]...)
Je codé ci-dessous:
package main
import (
"fmt"
)
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i, value := range slice {
if value%3 == 0 { // remove 3, 6, 9
slice = append(slice[:i], slice[i+1:]...)
}
}
fmt.Printf("%v\n", slice)
}
avec go run hello.go
, il panique:
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x4ef680, 0xc082002040)
D:/Go/src/runtime/panic.go:464 +0x3f4
main.main()
E:/Code/go/test/slice.go:11 +0x395
exit status 2
Comment puis-je modifier ce code pour obtenir les droits?
J'ai essayé ci-dessous:
1er, avec une déclaration goto
:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
Label:
for i, n := range slice {
if n%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
goto Label
}
}
fmt.Printf("%v\n", slice)
}
cela fonctionne, mais trop itération
2, utilisez une autre tranche de partage même tableau de support:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
dest := slice[:0]
for _, n := range slice {
if n%3 != 0 { // filter
dest = append(dest, n)
}
}
slice = dest
fmt.Printf("%v\n", slice)
}
mais je ne sais pas si celui-ci c'est mieux ou pas.
3, de Remove elements in slice, avec len
opérateur:
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i := 0; i < len(slice); i++ {
if slice[i]%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
i-- // should I decrease index here?
}
}
fmt.Printf("%v\n", slice)
}
qui dois-je prendre maintenant?
avec référence:
func BenchmarkRemoveSliceElementsBySlice(b *testing.B) {
for i := 0; i < b.N; i++ {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
dest := slice[:0]
for _, n := range slice {
if n%3 != 0 {
dest = append(dest, n)
}
}
}
}
func BenchmarkRemoveSliceElementByLen(b *testing.B) {
for i := 0; i < b.N; i++ {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for i := 0; i < len(slice); i++ {
if slice[i]%3 == 0 {
slice = append(slice[:i], slice[i+1:]...)
}
}
}
}
$ go test -v -bench=".*"
testing: warning: no tests to run
PASS
BenchmarkRemoveSliceElementsBySlice-4 50000000 26.6 ns/op
BenchmarkRemoveSliceElementByLen-4 50000000 32.0 ns/op
il semble supprimer tous les éléments en une seule boucle est mieux
En plus de cette réponse, il est plus efficace de itérer sur l'ensemble du réseau comme celui-ci et remplir un nouveau. Si vous utilisez des primitives simples ici, vous obtiendrez un gain de performances matérielles avec prédiction.Lire sur "Sympathie mécanique" sur le codage, en particulier dans Go, pour tirer parti des algorithmes du processeur. Bien que votre benchmark ne montre pas beaucoup de gains avec 9 numéros, essayez quelques millions pour voir les gains. – eduncan911