首先,c++,c等语言不存在这个问题,因为直接面对的是编译器,没有运行时环境。 性能优化可预期,可计算。
类似golang,java,python这种需要运行时环境的语言,往往存在理解不深入问题,特别是golang程序员普遍使用年限少,急于求成不求甚解,往往对golang的机制了解不够深入全面。
事由:
最近做Golang和linux技术交流,我发现不少的golang程序员是强行记忆了很多的概念,但是对概念理解不彻底,喜欢搞八股文。
把信息当做知识,把记忆力当做能力。 眼高手低者众。
个人一些比较肤浅的看法:
关于Golang编程语言并不存在多少高深莫测难以理解的东西,只要不断的深入思考,就能想明白。
(不存在跟高深的数学运算,例如爱因斯坦的 E=m c c之类的东西),编程是属于偏逻辑性的一个行业,虽然有时候也用了一些数学知识。
我认为,在Golang编程语言级别,Golang系统原生的数据结构,性能优化的可能几个点:
1,扩展map,加入命中率接口,
mm := make(map [string]int64_t, 0.8),例如数据读写属性,在0.8的命中率时整体效率最高,当map命中率低于80%,则启动双哈希定位策略,逐步迁移数据到新的哈希槽位。
不同场景下,数据属性不一样,增加接口可以较大幅度的提升整体平均性能,希望在1.80以后,golang实现模板化后提供此接口。 如果不行咱就亲自提交代码。
2,有一些计算量大的业务,希望独占GMP中的p线程,go <core_cpu [] string>
func(ctx *context) {
for {
fmt.Println(“task handler logic”)
}
}()
当然,这一条是技术可实现探讨,不是建议实现。 因为linux操作系统,golang,java等注重的是通用性,而不是注重特殊情况下性能的定制化。
希望可以作为一个特性加入,提供非标准化的接口。 因为golang在大数据,云计算的重度计算场景下用的越来越多。
3,channel,golang语言的channel机制其实实现的已经比较好,与GMP调度结合,能不拷贝,不调度的地方尽量不拷贝,不调度但,我认为还有优化空间。 chan 的G send 和recv阻塞队列,应该用双链表实现,而不是但链表实现。 双链表的好处是索引,移动节点为o(1),而不是o(N) 其中N是等待chan资源可用的go routine数量。
chan是用mutex进行保护,mutex也是一个重度的kernel接口,我认为应该用无锁化技术,配合cpu的特殊硬件电路:原子锁去实现。
可再次提升基于golang开发的应用性能几个百分点。
建议: golang,运行时环境官方有提供源码,在短期内,大概率官方是不会加入这些特性的,因此如果有需要的用户,建议可以自行在golang 运行时库的代码中进行修改,以提升性能。