Go 性能优化技巧 8/10

qyuhen · · 3779 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

尽管反射(reflect)存在性能问题,但依然被频繁使用,以弥补静态语言在动态行为上的不足。只是某些时候,我们须对此做些变通,以提升性能。 为便于阅读,以下示例均做了最大程度精简。 ![reflect1](http://studygolang.qiniudn.com/160607/116ce59acc17ca3eb189fcf74dadca3b.jpg) 如果是 reflect.Type,可将其缓存,避免重复操作耗时。但 Value 显然不行,因为它和具体对象绑定,内部存储实例指针。换个思路,字段相对于结构,除名称(name)外,还有偏移量(offset)这个唯一属性。利用偏移量,将 FieldByName 变为普通指针操作,就可以实现性能提升。 ![reflect2](http://studygolang.qiniudn.com/160607/378e9523ecedd8e0553723600299e6a1.jpg) 测试一下优化成果。 ![reflect3](http://studygolang.qiniudn.com/160607/d32c4646b5b169e8dc28cdbba616dc4f.jpg) ![reflect4](http://studygolang.qiniudn.com/160607/d2feac1191aa6cc049e1b3f32c53682b.jpg) 效果很好,不是吗?剩余的问题是,如何设计缓存结构,这个 offset 变量自然不能用于实际开发。 用 map[Type]map[name]offset?显然不行。每次执行 reflect.TypeOf,这于性能优化不利。可除了 Type,还有什么可以作为 Key 使用?要知道,接口由 itab 和 data 指针组成,相同类型(接口和实际类型组合)的 itab 指针相同,自然也可当作 key 来用。 ![reflect5](http://studygolang.qiniudn.com/160607/d7594789817ece18d33225d01ed33cdf.jpg) ![reflect6](http://studygolang.qiniudn.com/160607/c0c506b2909d6f8ac66370e9e4a23105.jpg) 虽因引入 map 导致性能有所下降,但相比直接使用 reflect 还是提升很多。 > 利用指针类型转换实现性能优化,本就是 “非常手段”,是一种为了性能而放弃 “其他” 的做法。与其担心代码是否适应未来的变化,不如写个单元测试,确保在升级时做出必要的安全检查。还有,本优化系列,仅仅提供一种优化思路,未必要照抄。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3779 次点击  
加入收藏 微博
2 回复  |  直到 2016-06-23 01:39:09
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传