如果你原来的代码是用 reflect 来实现,会得到性能提升。


但如果原本用的就是 interface,在目前(go 1.18, 1.19)暂时不会变快,甚至在某些情况下还会变慢。


原本的 func (interface{...}) ,比如 func Write(io.Writer, ...) 这样的方法不建议修改为 func [W io.Writter](W, ...),这样的修改在目前(go1.18,1.19)对性能有负面影响,因为目前的泛型实现(几乎)不做泛型实例化,导致泛型写法相比非泛型写法在运行时甚至可能进行额外的动态派发。


几个适合使用泛型的情况


bytes和string,如果你有某些函数既有string版本又有bytes版本(类似strings/byres.TrimSpace)则无脑使用泛型,比手写两个 string/[]byte 的函数还要快(当然要注意rune和unicode的问题,一些比较函数可能没法用泛型写出来)。


涉及到slice和map的 []T 和 map[K]V ,或者一些涉及算法的复杂结构体 (比如 Set[T]),这些场景没有更好的写法来实现类型安全。


高阶函数。比如 FilterInt(s []int, fn func(int) bool)) []int 可以修改为 Filter[T any)(s []T, fn func(T) bool)) []T ,但你甚至可以进一步修改为 Filter[T any, F func(T) bool))(s []T, fn F) []T。

虽然 go 默认不会做泛型高阶函数内联,但是说不定后面哪个版本就可以了呢。(其实你在 1.18 版本也可以用 -ldflags="-l=4" 来让这个 Filter 函数尝试进行内联,在可内联的情况下有手动内联等同的性能。)



目前来看没有什么能阻止go的开发组继续优化go的编译器,在未来版本支持泛型的实例化,但是目前还是类似于interface的实现(go起了个名字叫“gc shape”),所以一般来说还是会慢于codegen,go的编译期优化做的一般。


当然最快的还是针对基础类型做codegen,因为类型在编译时是确定的,编译器还能进行进一步优化。