Golang Go语言中针对reflect对func反射过慢的优化技巧

发布于 1周前 作者 itying888 来自 Go语言

Golang Go语言中针对reflect对func反射过慢的优化技巧

golang 的 func 的反射使用,目前还没有很合适的优化手段

但是可以很巧妙地绕过对 func 的反射

我个人语文水平难以表达出来,所以举一个实例进行说明

低效例子

gobench 测试大约 300 ns/op

type banana struct {
	value int
	value2 int
}

func   apple(b *banana)int{ return b.value }

func parse_func(fn interface{}) func() int{ fnt := reflect.TypeOf(fn) fnv := reflect.ValueOf(fn)

param := fnt.In(0).Elem()
return func() int {
	arg := reflect.New(param)
	resp := fnv.Call([]reflect.Value{arg}) // 严重耗时
	return resp[0].Interface().(int)
}

}

fn := parse_func(apple)

高效例子

gobench 测试大约 50 ns/op

type banana struct {
	value int
	value2 int
}

type iBanana interface { apple() int }

func (b *banana) apple() int { return b.value }

func parse_func(b iBanana) func() int{ t := reflect.TypeOf(b) param := t.Elem()

return func() int {
	arg := reflect.New(param).Interface().(iBanana)
	return arg.apple() // 无需反射
}

}

fn := parse_func(&banana{})


更多关于Golang Go语言中针对reflect对func反射过慢的优化技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

13 回复

都实现接口了还需要反射?

更多关于Golang Go语言中针对reflect对func反射过慢的优化技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


哦, 这是函数和参数都需要反射的场景下使用的

楼主好像搞反了反射的实际意义··

如果不是特殊的项目请保持简单,避免过度设计。

可以指点得更明白一点吗

我现在使用反射的一般目的是实现伪泛型

你这传入了一个 interface 然后一套骚操作又把它转回那个 interface 了,那为啥不直接调用.apple() 反射的意义是啥

arg := reflect.New(param).Interface().(iBanana)迷之操作。 return param.apple() 不行?


参数是需要反射产生的. 原来的场景是 函数和参数都需要反射, 修改后, 只需要对参数反射

那你应该是理解错了,如果你参数列表是动态的,那么你就不符合定义的接口了,也就无法传入了,你不能指定实体接口 而是用 interface{} 来反射

我要表达的就是 将参数写在 struct 里面, 然后用结构体方法的方式规避对 函数 的反射

你猜 (&banana{}).apple 是什么类型?
你这个 parse_func 纯粹多余。

在Golang中,reflect包提供了强大的反射功能,允许在运行时检查变量的类型和值,甚至调用函数。然而,反射操作相比直接调用会有一定的性能开销,特别是针对函数反射。以下是一些优化技巧,可以帮助缓解这一问题:

  1. 缓存反射结果:反射操作如reflect.TypeOfreflect.ValueOf是昂贵的,应尽量避免重复执行。可以将这些结果缓存起来,重复使用。

  2. 使用接口而非反射调用:如果可能,尽量通过接口来调用函数,而不是通过反射。接口调用在编译时解析,性能更高。

  3. 减少反射调用的次数:尽量减少反射调用的频率和深度,比如通过批量处理来减少反射操作的次数。

  4. 代码生成:对于性能要求极高的场景,可以考虑使用代码生成工具(如Go的go:generate指令)来自动生成高性能的代码,避免在运行时进行反射。

  5. 优化反射路径:对于反射调用,分析并优化反射路径上的热点代码,如使用更高效的算法或数据结构。

  6. 使用第三方库:一些第三方库可能提供了更高效的反射实现或替代方案,可以考虑使用这些库来优化性能。

总之,虽然reflect包提供了强大的功能,但在性能敏感的场景中应谨慎使用。通过缓存、接口调用、代码生成等技术,可以在一定程度上缓解反射带来的性能开销。

回到顶部