我正在嘗試使用Go語言,並且對它很陌生。我已經成功地閱讀了教程,現在正在編寫一個小程序來評估我通常所做的操作類型的性能。我有一段很長的float32類型,需要儘可能高效地將其轉換爲float64類型的片段。除了迭代切片的元素並通過輸出[i] = float64(data [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)
注意的是,在範圍內循環使用:=
會因爲圍棋的當前版本的變量被扔掉,每一次的,而不是被重用重建效率低下。使用range
而不是for i=0; i<n; i++
更有效,因爲它可以節省ar
上的邊界檢查。
這真的很有幫助。感謝您分享您的專業知識。 – user1503949
沒問題,歡迎來到Go的精彩世界! – Alasdair
我在過去幾天一直在玩它,但它確實看起來很好,很容易拾起。 – user1503949
對性能聲明持懷疑態度總是明智的。例如,「在範圍循環中使用:=會效率低下,因爲......變量每次都被丟棄並重新創建,而不是被重用。」
讓我們看看三次連續運行的基準結果。
floats_test.go
:
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() {}
輸出:
$ 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 $
按照要求通過已刪除的評論。這是一個只使用系統時間的基準。
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()
}
輸出:
$ 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 $
Hi peterSo,我在幾周前做過的基準測試中發現了:=範圍問題,並在Golang-Devs上報告了它。現在重做這個基準,我可以看出它們在兩者之間沒有區別。早期的基準很可能是有缺陷的。感謝您採取雙重檢查。 – Alasdair
- 1. 將一種類型轉換爲另一種類型
- 2. 如何將一種數據類型轉換爲另一種數據類型?
- 3. 如何將一種數據類型轉換爲另一種數據類型
- 4. 如何將屬性從一種類型轉換爲另一種?
- 5. 如何使用反射將一種類型轉換爲另一種類型?
- 6. 將集合從一種類型轉換爲另一種類型的策略
- 7. 轉換爲另一種類型的
- 8. AS3將一種類型轉換爲另一種
- 9. 創建一種函數將一種類型的函數轉換爲另一種類型
- 10. 如何將表列轉換爲另一種數據類型
- 11. 如何將通用數組轉換爲另一種類型?
- 12. 如何將時間戳轉換爲另一種數據類型?
- 13. 如何實現從一種類型到另一種類型的自動轉換?
- 14. 將字符串轉換爲另一種數據類型,Python
- 15. 從一個空類型轉換爲另一種可空類型
- 16. 通用如何將一種類型的數據轉換爲另一種類型的數據
- 17. 如何在vb.net中將數組從一種數據類型轉換爲另一種數據類型?
- 18. 使一種類型成爲一種類型或另一種類型
- 19. 如何將一種類型轉換爲與包名相同的多種類型?
- 20. 類型不匹配無法一種類型轉換爲另一種
- 21. 轉換類型ActiveRecord JSON輸出屬性爲另一種類型
- 22. 將一種類型的對象分配給另一種類型
- 23. 將一種類型的切片轉換爲等同類型切片的優雅方法?
- 24. 轉換字符串數組爲另一種類型
- 25. 將一種類型的列表轉換爲使用推土機的另一種類型的數組
- 26. 將一種類型的數據轉換爲另一種類型的設計模式
- 27. 如何在ColdFusion ORM中將實體從一種類型轉換爲另一種類型?
- 28. nhibernate將實體從一種類型轉換爲另一種類型:如何處理集合?
- 29. 將數據從一種類型轉換爲另一種類型的「正確」方式是什麼?
- 30. 通過重新解釋原始字節,從一種類型的numpy數組轉換爲另一種類型
不......即使這是一個內置的,它很難做的比迭代中,你的4行代碼會做同樣的方式的要素的任何其他。 –