Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何将一种数值类型的切片转换为另一种类型_Go - Fatal编程技术网

Go 如何将一种数值类型的切片转换为另一种类型

Go 如何将一种数值类型的切片转换为另一种类型,go,Go,我正在试验围棋语言,我对它很陌生。我已经成功地完成了教程,现在正在编写一个小程序,以评估我通常执行的操作类型的性能。我有一个很长的float32类型的切片,需要尽可能高效地将其转换为float64类型的切片。除了迭代切片的元素并通过输出[i]=float64(数据[i])显式转换单个元素的类型外,是否有一种方法可以用于转换整个切片而无需迭代?我尝试过搜索一个解决方案,但没有找到任何直接相关的解决方案。Go的级别非常低,这意味着迭代切片是最有效的方法。其他语言可能有用于这些事情的内置函数,但它们所

我正在试验围棋语言,我对它很陌生。我已经成功地完成了教程,现在正在编写一个小程序,以评估我通常执行的操作类型的性能。我有一个很长的float32类型的切片,需要尽可能高效地将其转换为float64类型的切片。除了迭代切片的元素并通过输出[i]=float64(数据[i])显式转换单个元素的类型外,是否有一种方法可以用于转换整个切片而无需迭代?我尝试过搜索一个解决方案,但没有找到任何直接相关的解决方案。

Go的级别非常低,这意味着迭代切片是最有效的方法。其他语言可能有用于这些事情的内置函数,但它们所做的只是通过切片进行迭代,没有迭代就无法完成。但是有一些技巧,特别是使用范围和避免索引切片,因为越界检查中存在开销。这将是最有效的:

func convertTo64(ar []float32) []float64 {
   newar := make([]float64, len(ar))
   var v float32
   var i int
   for i, v = range ar {
      newar[i] = float64(v)
   }
   return newar
}

slice32 := make([]float32, 1000)
slice64 := convertTo64(slice32)

请注意,在范围循环中使用
:=
效率低下,因为在当前版本的Go中,变量会被丢弃并每次重新创建,而不是重复使用。对于i=0,使用
range
代替
;我对性能声明持怀疑态度总是明智的。例如,“在范围循环中使用:=将是低效的,因为每次都会丢弃并重新创建变量,而不是重复使用。”

让我们看看连续三次运行的基准测试结果

浮动\u测试。转到

package main

import "testing"

var slice64 []float64

func FuncVar(f32 []float32) []float64 {
    f64 := make([]float64, len(f32))
    var f float32
    var i int
    for i, f = range f32 {
        f64[i] = float64(f)
    }
    return f64
}

func BenchmarkFuncVar(b *testing.B) {
    f32 := make([]float32, 1024)
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        slice64 = FuncVar(f32)
    }
}

func RangeVar(f32 []float32) []float64 {
    f64 := make([]float64, len(f32))
    for i, f := range f32 {
        f64[i] = float64(f)
    }
    return f64
}

func BenchmarkRangeVar(b *testing.B) {
    f32 := make([]float32, 1024)
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        slice64 = RangeVar(f32)
    }
}

func main() {}
主程序包
导入“测试”
var slice64[]float64
func FuncVar(f32[]float32][]float64{
f64:=make([]浮点64,len(f32))
变量f浮动32
变量i int
对于i,f=范围f32{
f64[i]=64(f)
}
返回f64
}
func BenchmarkFuncVar(b*testing.b){
f32:=make([]32,1024)
b、 ReportAllocs()
b、 重置计时器()
对于i:=0;i
输出:

$ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12260 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12125 ns/op 8192 B/op 1 allocs/op ok so/test 2.703s $ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12620 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12623 ns/op 8192 B/op 1 allocs/op ok so/test 2.782s $ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12730 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12971 ns/op 8192 B/op 1 allocs/op ok so/test 2.852s $ $ go build floata.go && ./floata FuncVar 10.479653966s RangeVar 10.208178244s $ go build floata.go && ./floata FuncVar 10.123357283s RangeVar 10.173007394s $ go build floata.go && ./floata FuncVar 9.935580721s RangeVar 10.109644784s $ go build floata.go && ./floata FuncVar 10.070552761s RangeVar 10.317730473s $ go build floata.go && ./floata FuncVar 10.075578601s RangeVar 10.012273678s $ $go test-v-run=-长凳=。 测试:警告:没有要运行的测试 通过 BenchmarkFuncVar 100000 12260 ns/op 8192 B/op 1 allocs/op 基准范围VAR 100000 12125 ns/op 8192 B/op 1 allocs/op ok so/测试2.703s $go test-v-run=-长凳=。 测试:警告:没有要运行的测试 通过 BenchmarkFuncVar 100000 12620 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12623 ns/op 8192 B/op 1 allocs/op 正常so/测试2.782s $go test-v-run=-长凳=。 测试:警告:没有要运行的测试 通过 BenchmarkFuncVar 100000 12730 ns/op 8192 B/op 1 allocs/op 基准范围100000 12971 ns/op 8192 B/op 1 allocs/op 正常so/测试2.852s $
应已删除评论的要求。这里有一个仅使用系统时间的基准测试

package main

import (
    "fmt"
    "time"
)

const N = 1e6

var f32 = make([]float32, 1024)
var slice64 []float64

func FuncVar(f32 []float32) []float64 {
    f64 := make([]float64, len(f32))
    var f float32
    var i int
    for i, f = range f32 {
        f64[i] = float64(f)
    }
    return f64
}

func BenchmarkFuncVar() {
    t1 := time.Now()
    for i := 0; i < N; i++ {
        slice64 = FuncVar(f32)
    }
    t2 := time.Now()
    fmt.Println("FuncVar", t2.Sub(t1))
}

func RangeVar(f32 []float32) []float64 {
    f64 := make([]float64, len(f32))
    for i, f := range f32 {
        f64[i] = float64(f)
    }
    return f64
}

func BenchmarkRangeVar() {
    t1 := time.Now()
    for i := 0; i < N; i++ {
        slice64 = RangeVar(f32)
    }
    t2 := time.Now()
    fmt.Println("RangeVar", t2.Sub(t1))
}

func main() {
    BenchmarkFuncVar()
    BenchmarkRangeVar()
}
主程序包
进口(
“fmt”
“时间”
)
常数N=1e6
var f32=make([]float321024)
var slice64[]float64
func FuncVar(f32[]float32][]float64{
f64:=make([]浮点64,len(f32))
变量f浮动32
变量i int
对于i,f=范围f32{
f64[i]=64(f)
}
返回f64
}
func BenchmarkFuncVar(){
t1:=时间。现在()
对于i:=0;i
输出:

$ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12260 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12125 ns/op 8192 B/op 1 allocs/op ok so/test 2.703s $ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12620 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12623 ns/op 8192 B/op 1 allocs/op ok so/test 2.782s $ go test -v -run=! -bench=. testing: warning: no tests to run PASS BenchmarkFuncVar 100000 12730 ns/op 8192 B/op 1 allocs/op BenchmarkRangeVar 100000 12971 ns/op 8192 B/op 1 allocs/op ok so/test 2.852s $ $ go build floata.go && ./floata FuncVar 10.479653966s RangeVar 10.208178244s $ go build floata.go && ./floata FuncVar 10.123357283s RangeVar 10.173007394s $ go build floata.go && ./floata FuncVar 9.935580721s RangeVar 10.109644784s $ go build floata.go && ./floata FuncVar 10.070552761s RangeVar 10.317730473s $ go build floata.go && ./floata FuncVar 10.075578601s RangeVar 10.012273678s $ $go build floata.go&&./floata FuncVar 10.479653966s 范围10.208178244s $go build floata.go&&./floata FuncVar 10.123357283s 范围变量10.173007394s $go build floata.go&&./floata FuncVar 9.935580721s 范围变量10.109644784s $go build floata.go&&./floata FuncVar 10.070552761s 范围10.317730473s $go build floata.go&&./floata FuncVar 10.075578601s 范围10.012273678s $
不即使这是一个内置的,它也只能像4行代码那样迭代元素,这真的非常有用。非常感谢您分享您的专业知识。过去几天我一直在玩弄它,但它确实看起来很好,而且很容易掌握。@Alasdair:您关于“:=范围内循环”的低效声明对堆栈或寄存器变量没有意义。我通过基准测试发现了这一点,并在golang-devs上报告了它。嗨,peterSo,我在几周前的基准测试中发现了:=范围问题,并在golang-devs上报告了它。现在重做这个基准,我可以看到,这两者之间没有区别。早期的基准测试很可能存在缺陷。谢谢你仔细检查。