一个针对 golang reflect 对 func 反射过慢的优化技巧

2020-12-22 14:08:39 +08:00
 fumeboy

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{})
1615 次点击
所在节点    Go 编程语言
12 条回复
wfhtqp
2020-12-22 14:16:46 +08:00
都实现接口了还需要反射?
fumeboy
2020-12-22 14:19:41 +08:00
@wfhtqp 哦, 这是函数和参数都需要反射的场景下使用的
ArJun
2020-12-22 14:26:28 +08:00
楼主好像搞反了反射的实际意义··
wfhtqp
2020-12-22 14:28:26 +08:00
如果不是特殊的项目请保持简单,避免过度设计。
fumeboy
2020-12-22 14:32:33 +08:00
@ArJun 可以指点得更明白一点吗
fumeboy
2020-12-22 14:37:08 +08:00
@ArJun 我现在使用反射的一般目的是实现伪泛型
Mitt
2020-12-22 22:56:21 +08:00
你这传入了一个 interface 然后一套骚操作又把它转回那个 interface 了,那为啥不直接调用.apple() 反射的意义是啥
eudore
2020-12-23 08:44:31 +08:00
`arg := reflect.New(param).Interface().(iBanana)`迷之操作。 `return param.apple()` 不行?
fumeboy
2020-12-23 12:21:50 +08:00
@eudore
@Mitt 参数是需要反射产生的. 原来的场景是 函数和参数都需要反射, 修改后, 只需要对参数反射
Mitt
2020-12-23 12:34:21 +08:00
@fumeboy 那你应该是理解错了,如果你参数列表是动态的,那么你就不符合定义的接口了,也就无法传入了,你不能指定实体接口 而是用 interface{} 来反射
fumeboy
2020-12-23 12:37:38 +08:00
@Mitt 我要表达的就是 将参数写在 struct 里面, 然后用结构体方法的方式规避对 函数 的反射
reus
2020-12-26 16:51:49 +08:00
你猜 (&banana{}).apple 是什么类型?
你这个 parse_func 纯粹多余。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/737835

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX