Go1.18新特性使用Generics泛型進行流式處理
前言
Stream 是一個基于 Go 1.18+ 泛型的流式處理庫, 它支持并行處理流中的數(shù)據(jù). 并行流會將元素平均劃分多個的分區(qū), 并創(chuàng)建相同數(shù)量的 goroutine 執(zhí)行, 并且會保證處理完成后流中元素保持原始順序.
GitHub - xyctruth/stream: A Stream library based on Go 1.18+ Generics (Support Parallel Stream)
安裝
需要安裝 Go 1.18+ 版本
$ go get github.com/xyctruth/stream
在代碼中導(dǎo)入它
import "github.com/xyctruth/stream"
基礎(chǔ)
s := stream.NewSliceByOrdered([]string{"d", "a", "b", "c", "a"}). Filter(func(s string) bool { return s != "b" }). Map(func(s string) string { return "class_" + s }). Sort(). Distinct(). ToSlice() // 需要轉(zhuǎn)換切片元素的類型 s := stream.NewSliceByMapping[int, string, string]([]int{1, 2, 3, 4, 5}). Filter(func(v int) bool { return v >3 }). Map(func(v int) string { return "mapping_" + strconv.Itoa(v) }). Reduce(func(r string, v string) string { return r + v })
類型約束
any
接受任何類型的元素, 所以不能使用 ==
!=
>
<
比較元素, 導(dǎo)致你不能使用 Sort(), Find()...等函數(shù) ,但是你可以使用 SortFunc(fn), FindFunc(fn)... 代替
type SliceStream[E any] struct { slice []E } stream.NewSlice([]int{1, 2, 3, 7, 1})
comparable
接收的類型可以使用 ==
!=
比較元素, 但仍然不能使用 >
<
比較元素, 因此你不能使用 Sort(), Min()...等函數(shù) ,但是你可以使用 SortFunc(fn), MinFunc()... 代替
type SliceComparableStream[E comparable] struct { SliceStream[E] } stream.NewSliceByComparable([]int{1, 2, 3, 7, 1})
constraints.Ordered
接收的類型可以使用 ==
!=
>
<
, 所以可以使用所有的函數(shù)
type SliceOrderedStream[E constraints.Ordered] struct { SliceComparableStream[E] } stream.NewSliceByOrdered([]int{1, 2, 3, 7, 1})
類型轉(zhuǎn)換
有些時候我們需要使用 Map
,Reduce
轉(zhuǎn)換切片元素的類型,但是很遺憾目前 Golang 并不支持結(jié)構(gòu)體的方法有額外的類型參數(shù),所有類型參數(shù)必須在結(jié)構(gòu)體中聲明。在 Golang 支持之前我們暫時使用臨時方案解決這個問題。
// SliceMappingStream Need to convert the type of slice elements. // - E elements type // - MapE map elements type // - ReduceE reduce elements type type SliceMappingStream[E any, MapE any, ReduceE any] struct { SliceStream[E] } s := stream.NewSliceByMapping[int, string, string]([]int{1, 2, 3, 4, 5}). Filter(func(v int) bool { return v >3 }). Map(func(v int) string { return "mapping_" + strconv.Itoa(v) }). Reduce(func(r string, v string) string { return r + v })
并行
Parallel
函數(shù)接收一個 goroutines int
參數(shù). 如果 goroutines>1 則開啟并行, 否則關(guān)閉并行, 默認流是關(guān)閉并行的。
并行會將流中的元素平均劃分多個的分區(qū), 并創(chuàng)建相同數(shù)量的 goroutine 執(zhí)行, 并且會保證處理完成后流中元素保持原始順序.
s := stream.NewSliceByOrdered([]string{"d", "a", "b", "c", "a"}). Parallel(10). Filter(func(s string) bool { // 一些耗時操作 return s != "b" }). Map(func(s string) string { // 一些耗時操作 return "class_" + s }). ForEach( func(index int, s string) { // 一些耗時操作 }, ).ToSlice()
并行類型
First
: 一旦獲得第一個返回值,并行處理就結(jié)束. For: AllMatch, AnyMatch, FindFuncALL
: 所有元素都需要并行處理,得到所有返回值,然后并行結(jié)束. For: Map, FilterAction
: 所有元素需要并行處理,不需要返回值. For: ForEach, Action
并行 goroutines
開啟并行 goroutine 數(shù)量在面對 CPU 操作與 IO 操作有著不同的選擇。
一般面對 CPU 操作時 goroutine 數(shù)量不需要設(shè)置大于 CPU 核心數(shù),而 IO 操作時 goroutine 數(shù)量可以設(shè)置遠遠大于 CPU 核心數(shù).
CPU 操作
NewSlice(s).Parallel(goroutines).ForEach(func(i int, v int) { sort.Ints(newArray(1000)) // 模擬 CPU 耗時操作 })
使用6個cpu核心進行基準測試
go test -run=^$ -benchtime=5s -cpu=6 -bench=^BenchmarkParallelByCPU goarch: amd64 pkg: github.com/xyctruth/stream cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz BenchmarkParallelByCPU/no_parallel(0)-6 717 9183119 ns/op BenchmarkParallelByCPU/goroutines(2)-6 1396 4303113 ns/op BenchmarkParallelByCPU/goroutines(4)-6 2539 2388197 ns/op BenchmarkParallelByCPU/goroutines(6)-6 2932 2159407 ns/op BenchmarkParallelByCPU/goroutines(8)-6 2334 2577405 ns/op BenchmarkParallelByCPU/goroutines(10)-6 2649 2352926 ns/op
IO 操作
NewSlice(s).Parallel(goroutines).ForEach(func(i int, v int) { time.Sleep(time.Millisecond) // 模擬 IO 耗時操作 })
使用6個cpu核心進行基準測試
go test -run=^$ -benchtime=5s -cpu=6 -bench=^BenchmarkParallelByIO goos: darwin goarch: amd64 pkg: github.com/xyctruth/stream cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz BenchmarkParallelByIO/no_parallel(0)-6 52 102023558 ns/op BenchmarkParallelByIO/goroutines(2)-6 100 55807303 ns/op BenchmarkParallelByIO/goroutines(4)-6 214 27868725 ns/op BenchmarkParallelByIO/goroutines(6)-6 315 18925789 ns/op BenchmarkParallelByIO/goroutines(8)-6 411 14439700 ns/op BenchmarkParallelByIO/goroutines(10)-6 537 11164758 ns/op BenchmarkParallelByIO/goroutines(50)-6 2629 2310602 ns/op BenchmarkParallelByIO/goroutines(100)-6 5094 1221887 ns/op
項目地址 https://github.com/xyctruth/stream
以上就是Go1.18新特性使用Generics泛型進行流式處理的詳細內(nèi)容,更多關(guān)于Go1.18 Generics泛型流式處理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang Gin框架實現(xiàn)文件下載功能的示例代碼
本文主要介紹了Golang Gin框架實現(xiàn)文件下載功能的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12Go實現(xiàn)分布式系統(tǒng)高可用限流器實戰(zhàn)
這篇文章主要為大家介紹了Go實現(xiàn)分布式系統(tǒng)高可用限流器實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06Golang 使用http Client下載文件的實現(xiàn)方法
今天小編就為大家分享一篇Golang 使用http Client下載文件的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07使用gopkg.in/yaml.v3?解析YAML數(shù)據(jù)詳解
這篇文章主要為大家介紹了使用gopkg.in/yaml.v3?解析YAML數(shù)據(jù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09