Go 快的原因

2014-06-07 17:07:28 +08:00
 Livid
http://dave.cheney.net/2014/06/07/five-things-that-make-go-fast
4318 次点击
所在节点    Go 编程语言
17 条回复
wwek
2014-06-07 17:29:48 +08:00
有人上个翻译么`
canesten
2014-06-07 17:55:41 +08:00
第一 干净的类型
对比的是Java煞笔一样的包装类型
第二 内联和删除一辈子都不会被运行的代码
内联Java也可以有,只是程序员的习惯不好,该final的类都写成final就是了
代码剪裁这个JVM貌似也有优化
第三 Go自己会优化内存的分配,尽量不用堆上分配的内存来避免GC造成的开销
第四 Go有协程
第五 更先进的栈内存管理机制
yukirock
2014-06-07 18:01:09 +08:00
@canesten
Java 對類或者方法用 final 更多只是強調在繼承關係中禁止重寫而非內聯。性能上不見得有什麼優勢。
ovear
2014-06-07 18:18:12 +08:00
@canesten golang的gc。。。简直是没话说,就是内存侧漏侧漏侧漏。
突然发现java有最大heap挺不错的。。至少不会因为一个app泄露了,系统就跪了。。
canesten
2014-06-07 18:23:21 +08:00
@yukirock
Java的内联是在JIT阶段做的
HotSpot的JIT编译器分两个client模式的C1,server模式的c2
引一段撒加的文

C1在方法内联上只用了比较简单的策略:它能内联可以静态判定实现者的、字节码大小不大于MaxInlineSize(= 35字节)的方法。这包括静态方法、private的实例方法以及final的虚方法。同时它也可以依赖类层次分析(class hierarchy analysis,CHA)来内联只有单一实现者的虚方法。
C2在方法内联上则更为激进:除了C1能内联的之外,C2还能使用profile信息来内联无法静态判定实现者的方法——假如profiling发现某个虚方法调用点实际只调用到了1、2个实现者,那么C2就可以把这1、2个实现者给内联进来。


http://hllvm.group.iteye.com/group/topic/39806
hooluupog
2014-06-07 18:25:55 +08:00
接楼上的解释:
第一个说的是值类型。Go的int32正好是4个字节,python需要消耗6倍多的内存空间来查找类型信息,引用计数等等的附加操作(当然python写起来确实很方便,比如int是任意长度的,它本身就是个对象)。java虽然也是4个字节表示整型(java是有原始类型的),但当在collection数据结构(例如list,map)中使用时需要转换为integer对象(拆箱装箱操作),也会产生额外开销,其实这个是吐槽java的泛型实现的问题以及java没有值类型(java 9应该会有)。Go可以在连续的内存空间存储一个大的数据结构(比如struct),这样省去了离散分配时间接引用的开销,提高缓存的命中率,自然效率更高。 [注:java这些方面应该有jvm和jit优化进行一定程度的优化,比如调节高栈和堆的最小值最大值,现在java有可视化的工具辅助做这个调优工作]
第三个说的是逃逸分析。尽可能的让变量分配在栈上而不是分配在堆上减少gc的开销;
第五个是说Go由之前的分段式栈换成了新的连续式栈。解决了hot split的问题(有点像操作系统中的分页调度时的抖动现象导致的性能下降)。
canesten
2014-06-07 18:28:50 +08:00
@ovear
其实我是Java党
但是Java的包装类型确实是比较奇葩
谁都可以吐槽这个
hooluupog
2014-06-07 18:31:44 +08:00
@canesten Go现在应该是做到了c1的程度,部分情况下能做到一点点c2。Go对非叶子节点的函数目前好像还无法内联,好像是其他方面的工作(主要和gc的精确性有关)完成之前不敢那么激进。
canesten
2014-06-07 18:42:19 +08:00
@hooluupog
我还是挺看好Go的
毕竟一个大牛们造的新语言
刚开始不成熟也是因为大牛们自己能力强
内存泄露什么的良好的代码习惯就人工控制了
慢慢还是会演进的
但是我觉得从生态和工具链上追上Java还是有很长远的路要走
reusFork
2014-06-07 18:50:22 +08:00
@ovear 1.3就已经是精确gc了,不会泄漏了
ovear
2014-06-07 18:53:34 +08:00
@reusFork 改天去试试,之前用开源的go项目,几乎每个都有内存侧漏。。简直无法接受

@canesten 其实怎么说呢,我并没有觉得Java的包装类型很傻比。。求解释。不过我吐槽的是GC。。
canesten
2014-06-07 19:02:40 +08:00
@ovear
因为Java的包装类型是基于泛型这个语言缺陷设计出来的
所以吐槽包装类型也是在变相吐槽Java糟糕的泛型设计吧
Java既没做到像SmallTalk一样把值类型作为一个纯对象
也没做到让他和C一样是一个纯粹的值
弄了两套东西
让人初学者很迷惑的
包装类型->值类型时候Null的判断也烦的很
你从集合类中取出一个包装类型的时候总是不能直接判断值
要先判断Null
ovear
2014-06-07 19:04:26 +08:00
@canesten java会自动拆装箱并且设定默认值的说吧。。我从来没有在包装类中判断Null。。。难道我的用法一直错了
canesten
2014-06-07 19:10:03 +08:00
@ovear
sorry
是我没说清楚
我说的是当这东西是null的时候没有个默认值
比如
HashMap<String, Integer> xx;
Integer weight = xx.get("id");
然后就要先判weight是不是null

或者
Class A{
Integer weight;
}

A a = new A();
不能直接a.weight > 123
ahr0u
2014-06-07 19:11:36 +08:00
比起swift如何呢
lidashuang
2014-06-07 19:14:36 +08:00
@ahr0u swift 只能写写ios
ovear
2014-06-07 20:24:00 +08:00
@canesten 呃。。Collection里面这点的确比较狗屎

但是自己的类里面用int就够了。。会自带原生赋值。。

不过据说java有计划取消原生类型(Java在Oracle手上后就是坑坑坑。。)

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

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

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

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

© 2021 V2EX