1
bobuick 2016-01-06 16:39:02 +08:00
因为它们和终极要搞的对象(01)离的太远了, 中间次数转换太多了
|
2
yxzblue 2016-01-06 16:40:17 +08:00 1
看看新头像
|
3
temberature OP @bobuick 编译之后不都是二进制了吗,感觉理论上可以没区别
|
4
KyleMeow 2016-01-06 16:44:38 +08:00 via iPhone
@temberature 生成的汇编代码不同。就像写作文一样,同一件事可以两三百字写完,也能写一本书。
|
5
asdwfwqd 2016-01-06 16:46:42 +08:00
例如 java 一次编译,多平台都可以运行,但是是运行在虚拟机里的,性能比不上汇编和 c
|
6
thxmem 2016-01-06 16:47:00 +08:00 via Android
条条大路通罗马
|
7
temberature OP @KyleMeow 那是不是编译器写的不够好,就像作文里很多废话
|
8
temberature OP @asdwfwqd 我理解原因是需要动态决定很多变量,如果只针对一个机器,就可以排除这些因素
|
9
KyleMeow 2016-01-06 16:53:56 +08:00 via iPhone
@temberature 不一定。同样是 C 语言的话, Intel 的 icc 就可以产生效率比 gcc 高得多的代码。但是不同语言不能比,思路不同,实现方式也不同。可能 import 一个大包只是为了用一个超级小的功能,但是对象创建和初始化过程必不可少。
|
10
cfans1993 2016-01-06 16:55:20 +08:00 via Android
两大要点:效率,安全
看你侧重哪一个 |
11
jasontse 2016-01-06 16:58:27 +08:00 via iPad
创造性的东西怎么能说清楚
|
12
standin000 2016-01-06 16:59:45 +08:00
你是指编译性能还是写代码性能?个人觉得写代码性能差异大些
|
13
airqj 2016-01-06 17:01:03 +08:00
直接挠痒痒和隔着衣服挠痒痒
感觉是一样的吗? |
14
temberature OP @KyleMeow 比应该还是可以比的吧,我想问的是语言层面的, import 感觉是更高一级的问题
|
15
temberature OP @cfans1993 如果只考虑性能呢
|
16
temberature OP @jasontse 就是不太明白才想问下,不过感觉是有答案的
|
17
BeanMrx 2016-01-06 17:05:50 +08:00 via Android
简单的说就是机器比人便宜!用人话写程序再翻译成不是人话,总要消耗一些但是值得的!
|
18
temberature OP @standin000 就是不同语言实现同一件事,理论上可以做到消耗完全一样的时间和资源吗
|
19
KyleMeow 2016-01-06 17:09:16 +08:00 via iPhone
@temberature 同样的汇编代码都无法保证消耗一样的时间和资源,除非是单线程的操作系统
|
20
msg7086 2016-01-06 17:09:49 +08:00 via Android
|
21
temberature OP @airqj 这个确实不一样,但好像不太能类比,想不到更合适的,但编程语言是有翻译过程的
|
22
KyleMeow 2016-01-06 17:10:07 +08:00 via iPhone
@temberature 单进程.. 上条说错了
|
23
temberature OP @BeanMrx 翻译好再执行,那一次就不存在消耗了
|
24
temberature OP @KyleMeow 主要还想问的是理论问题,确实还会有很多工程问题
|
25
pythonee 2016-01-06 17:14:30 +08:00
垠神说过,语言是语言,语言决定了语义和表达力,其余的取决于编译器实现的好坏
|
26
temberature OP @msg7086 那问题就变成了导致不太可能的原因又是什么呢
|
27
temberature OP @pythonee 那看来上帝可以实现最好的编译器
|
28
hyz0805 2016-01-06 17:16:44 +08:00
对都是编译执行的语言,最直接表现是编译后的机器代码行数更多,
比如实现相同功能, C 语言的代码链接编译成的汇编代码再编译成机器语言后要比其他高级语言的更高效。 对于解释执行的语言,还有个解释代码的阶段,因此性能上会再打折扣。 |
29
zenhand 2016-01-06 17:18:38 +08:00
比如一个任务, print 100,可以直接 print 100,也可以 print 1+1+1+1.....+1+1,一直加到一百,其中的计算量显然不同,我喜欢的 python 就是这种混帐事干的太多了,所以效率才低的。
|
30
qian19876025 2016-01-06 17:19:24 +08:00
同样功能的程序 使用不同的语法产生的 二级制不一样
做一个不恰当的比喻 同样都是唱歌而且也是同样一首歌 不同的人唱吹来的音调完全不一样 你听到的效果也完全不同 但是他们的发声结构确实大体相同的 只不过材料原因 或者发声方法不一样 |
31
msg7086 2016-01-06 17:19:30 +08:00 via Android
@temberature 高级语言会容忍用户的懒惰,所以会代替人做很多的工作,比如检查数据合法性,管理内存等等,自然比天天加班用低级语言写出来的代码要慢一些。
|
32
temberature OP @hyz0805 现实确实如此。解释型好像也可以编译执行
|
33
KyleMeow 2016-01-06 17:21:35 +08:00 via iPhone
@hyz0805 也不能简单从行数来判断。还有一些 SIMD 和附加指令集指令,另外每个指令执行的时间周期也不等。其实这个最考验编译器优化水平了,或者为了兼容性而不能用一些新指令。
|
34
temberature OP @zenhand 但这种事是可以避免的,语言的升级有的就是做的这种事吧
|
36
temberature OP @msg7086 然而还有改进的空间
|
37
roychan 2016-01-06 17:26:01 +08:00
楼主头像好面熟。。 golang?
|
38
leavic 2016-01-06 17:26:12 +08:00
从 8 楼到 1 楼,最快的方式肯定是跳楼,但跳楼。。。。。
所以有了电梯和楼梯。 |
39
temberature OP @roychan 是,当时传头像,刚好看到,惭愧却没学过 go
|
40
loading 2016-01-06 17:28:38 +08:00 via Android
别说编译过了,两个人写汇编都有巨大差异!
|
41
temberature OP @leavic 但这两件事结果不一样,相信跳过的都知道
|
42
MiguelValentine 2016-01-06 17:30:14 +08:00
作为游离于一个实模式/保护模式的开发者 性能差异产生于编译后的逻辑 在汇编模式查看,高级语言写出来的东西,都是在曲线救国啊。误国啊。真的= =
|
43
KyleMeow 2016-01-06 17:30:16 +08:00 via iPhone
其实楼主可以去了解下语言的翻译( translate )、编译( compile )、解释( interpret )的区别。并不是所有语言都有完全等价的写法,即相互翻译。
|
44
temberature OP @loading 语言和个人确实都是影响因素,而且语言还会影响到人
|
45
temberature OP @MiguelValentine 似懂非懂,不明觉厉
|
46
temberature OP @KyleMeow 恩呢,虽然具体不清楚,但能感觉到不同语言表达力的区别。想问的还是能不能对二进制做精确的抽象
|
47
whitefable 2016-01-06 17:49:10 +08:00
um...我觉得一种理解嘛...就看你怎么定义一件事情了
如果说只是实现你所需要的要求...自然方法是不一样的...过程不一样所消耗的资源也是不一样...但最终你看到的结果是一样的...大概就是大家所说的编译的过程什么的啦 如果说你要定义到汇编或者机器码都是一样的话...其实貌似执行起来也是不可能完全一致的=.=在我的学科内...电子电路这种东西嘛...就没啥说一定是确定的...你回到电路的最基本层次最基本结构大概也就知道那个执行起来是不可能完全一样的或者说只会在一定范围内是对的但你要精确解还真没有...因此你也无法预测到下一次执行所需时间的精确解...自然就会产生效率差异...当然这部分就不是高级语言 or 程序层次上的效率差异了...所以我觉得语言上的那层差异来自于编译那部分=.= |
48
honam 2016-01-06 17:51:50 +08:00 1
这事就好比不同人用同一种语言写的程序效率不一样那么简单
|
49
KyleMeow 2016-01-06 17:52:43 +08:00 via iPhone
@temberature 连 C++ 这一门语言的各编译器都无法做到 ABI 统一,其他语言之间等价语句生成的二进制代码可以说是 100% 不同。遇到 JIT 动态优化的语言,同样代码每次执行的指令都可以不同。
|
50
aisk 2016-01-06 17:58:20 +08:00
其实最关键的是变量类型是否确定,如果不确定这个开销怎么也不能省了,不管你是解释执行,还是 JIT 😂
|
51
aisk 2016-01-06 17:58:35 +08:00
还有 GC 的问题,对性能影响也很大。
|
52
sandideas 2016-01-06 18:04:32 +08:00
我老师以前上 JAVA 课又说过一个例子。。
就是大致相当于我们人吃饭, JAVA 相当于是把锅里的饭装到碗里吃。而 C 相当于是直接趴锅里吃。。 当然 C 的效率高。 JAVA 的 class 文件虽然也是二进制的,但是不能够直接在 CPU 上执行,需要 JVM 。。相当于是套了个虚拟机。 然后 js 这样的语言需要检查语法,编译这样的。。而且这些语言设计的时候就是想要易用性,而不是效率。为了易用性通用性所以用计算机资源去完成。 |
53
CRVV 2016-01-06 18:04:45 +08:00
个人观点,不同语言效率不同的主要原因是语义不同
比如 C 和 Python 里类似的语句 int i = 0; i++; 和 i = int(0) i += 1 这两句的意思不一样,速度也不一样 再比如 std::sort 和 qsort ,都是快速排序,但 std::sort 的速度快 如果语义完全一样,编译器 /解释器就可以用相同的方式来执行,效率就可以一样。 当然实际情况是不同语言的编译器 /解释器的实现不一样,速度也总会有差别的 |
54
b821025551b 2016-01-06 18:05:54 +08:00
手工切图和 dreamweaver 切图的区别
|
55
georgetso 2016-01-06 18:06:49 +08:00
不同的性能代价,换来不同的其它效率的收益,比如常见的开发效率
|
56
temberature OP @KyleMeow 这也是学编译原理的作用吧
|
57
temberature OP @georgetso 一般事都是不可兼得,但在这件事上好像有可能
|
58
wy315700 2016-01-06 18:20:51 +08:00 1
同样一个意思,中文可能 20 个字,英文要 200 个字母,还有其他语言,
打个比方而已,性能差距就是这么来的, 同样一个功能,可能汇编只要 20 条指令, C 编译出来的要 50 条,其他语言需要 200 条或者更多 |
59
contmonad 2016-01-06 18:21:54 +08:00
主要还是语言实现有性能差异,在理想情况下,如果编译器足够聪明最后优化得到的机器码都差不多。但是不同的语言设计导致“理想编译器”的实现难度不一。如果你业余时间设计一种跟 JavaScript 类似的动态类型语言,你肯定没法像财大气粗的 Google 一样搞一个 V8 这种级别的 JIT ,然后就会发现 JS 的性能比你的玩具语言高到不知道哪里去了
|
60
temberature OP @wy315700 说不定有一天,人类的语言和计算机语言在发展到极致的时候能融合,也是黑客帝国来临的一天
|
61
acros 2016-01-06 18:33:51 +08:00 via iPhone
c , c++能直接操作内存,手动管理分配,比 gc 效率不知道高到哪里去了。 啊,出问题的时候,你也不知道自己死到哪里去了。
|
62
h4x3rotab 2016-01-06 19:03:01 +08:00 via iPhone
最大的锅其实是 gc ,别的都还好说
|
63
qian19876025 2016-01-06 19:15:09 +08:00
@temberature 你说的是 MIT 那群人搞的什么在已有可执行的软件上 自动生成新软件?
不过你说的那种 怕是 说的机器人能听懂你的语言 然后 机器人执行你的命令 真到那个时候 还要毛线程序员啊 到那时候直接都是一群肥猪 |
64
jsyangwenjie 2016-01-06 19:41:08 +08:00
你是要语言的表达能力呢,还是要其性能呢(当然这跟编译器实现有关),还是要安全呢?
|
66
gamexg 2016-01-06 19:46:36 +08:00 via Android
动态类型需要检查类型。
静态语言垃圾回收之类的也会消耗性能。 还有很多安全检查,例如 null 指针。 |
67
YuJianrong 2016-01-06 21:22:08 +08:00 2
我觉得这个提法本身就是错误的。
对于编译(以及有 JIT 的语言比如 java/JS )语言来说,语言没有性能区别,只有功能区别,所谓性能区别是因为功能不一样,那跑的机器码当然不一样,性能就不一样了。 所以如果功能完全一样, C 和 java 的代码性能也是一样的(比如最基础的一些整数加减计算, JIT 出来的 java 也不可能跑得慢),但问题就是很多功能其实是不一样的。比如 C 的字符串处理,就是处理 8bit 的 char 数组而已,然而 java 的字符串处理,就是处理有这边界保护等等复杂逻辑的一个数据对象,性能自然不可能一样。 提到 web 领域的话,微博领域也有高性能计算解决方案,就是 mozilla 提出的 asm.js ,在 js 中加入一些兼容的修饰之后,就可以让 JIT 将这种 JS 编译为性能更好的机器码,现在已经得到很多浏览器的广泛支持。在这个之外,还有 intel 提出的 SIMD.js 扩展,可以使 JS 能利用并行指令集来加速计算,不过貌似并没有得到广泛支持。 Asm.js 的下一步是 webAssembly ,就是 JS 运行时代码的二进制表达,可以在封装上也达到类似原生的代码和解析效率。 |
68
temberature OP @qian19876025 可是要做什么是机器决定不了的,成了大头娃娃倒是有可能,哈哈...
|
69
temberature OP @YuJianrong 有时间仔细看看你说的
|
70
msg7086 2016-01-06 23:12:25 +08:00 1
#36 @temberature 是可以提升。
世界上可以提升的东西有很多很多。 有很多人还在贫困线上挣扎,吃不饱穿不暖,朝不保夕。 如果真的有什么东西急着要提升的,那就提升下他们的生活质量吧。 相比起来一个语言的运算性能算什么。 反过来说,如果一个语言的性能已经能够接受了,那么再榨取空间无非只是锦上添花。 就说 JavaScript ,在 V8 引擎出现之前, JS 的运行效率并不高,然而 JS 也活了那么多年了。 现在性能高了,无非也就是锦上添花,跑些 SPA 跑些好看的效果,并没有实质性地改变人的生活。 至于像 PHP 这样的,如果没有那么高的性能会怎么样呢? 其实也不会怎么样。十多年前 PHP4.x 时代照样一大批论坛在跑啊,照样造就了很多高质量的网站啊。 无非就是多花点钱而已。 能用一点小钱就能解决的问题,都不算是问题。 多买一台服务器撑死也就一两千刀。 优化一个语言的性能,成本轻松就可以超过一百万刀。 不是一个数量级上的东西。 |
71
temberature OP @msg7086 你说的没错,但有些不同意见,对于不同对象算法不一样,比如 v8 和 hhvm ,对于 google 和 facebook 来说,改进基础设施的回报就比只花钱划算,再比如一个压缩算法会在全世界减少多少储存成本,基础研究从来都是算大帐,也许我较真了,只想说明这个问题的意义。 ps:突然想起一篇文章,非洲那么多挨饿的人,为什么不拿探索太空的钱帮助他们?
|
72
msg7086 2016-01-06 23:39:53 +08:00
@temberature 是的,所以是否要去改进一个语言,应当是成本导向而不是仅仅因为某个语言很慢。
创业公司偏向于 Ruby 和 Python 之类的语言,纯粹就是因为他们给企业节约了大量的成本,减少了开发周期,提高了可维护性,便于后期继续发展。 但是一旦到了某个瓶颈阶段,改进语言比买服务器便宜的时候,才会再去花大力气改进语言本身。 PS: 压缩算法其实快到头了,再挖掘下去意义已经不是辣么大了。要减少存储成本不如减少存储器的成本。 |
73
RqPS6rhmP3Nyn3Tm 2016-01-07 00:02:16 +08:00 via iPad
@KyleMeow 三者之间有什么不同呢?
|
74
imgalaxy 2016-01-07 02:02:38 +08:00 via Android
别说计算机语言了…
人说话不也是一样的么 |
75
Perry 2016-01-07 02:44:27 +08:00
把这个世界都想的太简单。
|
76
KyleMeow 2016-01-07 09:34:12 +08:00
@BXIA 翻译( translate )指的是两种同等级语言之间的保持逻辑结构的等价转换,比如 C++ 翻译为 Java ,保持原有的函数结构和逻辑,可以无损地转换回来,正如英语中 translate 还有平移的意思;编译( compile )是高级语言转为低级语言(不一定是汇编,只要有损、降级就是编译),这个过程不可逆,比如说汇编就难以恢复为原来高级语言的代码结构;解释( interpret )则是在运行时将高级语言解释为一句一句的机器指令并执行。
不过现在很多语言都是混合的,既有翻译也有编译还有解释。 |
77
Zero24 2016-01-07 10:18:35 +08:00
开发效率 vs 性能
|
78
abxialiang 2016-01-07 10:29:05 +08:00
假设汇编是最底层语言,拿 c 和 c#来对比,你的意思是实现同样的功能,c 和 c#应该可以编译出同样的汇编代码,那样运行性能就一样了是吧,实际上很困难,因为机器和人脑的运行方式有很大的区别,高级的语言更接近人脑的思维方式,但付出的代价是用了很多额外的逻辑来将机器尽量模拟成人脑,语言越高级,这种额外的逻辑就越多,而这些额外的逻辑最终"编译"进了汇编代码,为什么编译器不能在在编译时把这些"额外的逻辑"去掉只保留核心汇编代码呢?简单的也许可以,像代码 1+2+...n,有些编译器直接转化为数学公式(1+n)*n/2 进行计算了,复杂点的无法那么智能的去掉了,往往一个项目中复杂的东西比较多.编译器就是个翻译器,在翻译成汇编时如果太"智能",自以为是的抽取核心思想,指不定把不该去掉的东西去掉了,还是直译稳妥,毕竟人脑的思想还太过深邃.
~~这些是我个人的一些想法,说的不恰当的地方请多包涵. |
79
GentleSadness 2016-01-07 13:58:55 +08:00
语言性质问题、、函数式的惰性求值导致内存占用高,但命令式的求值导致 CPU 浪费,侧重点什么的,还有静态和动态的,什么鬼都有,抽象层次的不同,侧重点的不同导致性能的差异
|
80
standin000 2016-01-07 14:08:23 +08:00
@temberature 斧头和剑砍人的效果不会一样的。
|
81
codesun 2016-01-07 14:53:42 +08:00
编译器本质是一种映射程序,编译器从其提供的语法映射到 IR , IR 经过优化可导出汇编或直接经由 codegen 生成本地代码。
先不说别的,虽然二进制只有 0 和 1 ,但是组合爆炸,其次语言的语法不同,生成的下层表示也不同,编译器的处理方式不同,下层的代码也不同,还有最重要的优化器。 一般来说,静态编译语言速度优于解析型,即使后者有 JIT ,也很难超越前者,当然除非前者没有优化器,而且 codegen 很烂,那就另当别论了。 同样是编译型,内部也相差很大,主要取决于语言是不是提供了很多语法糖,是不是由编译器添加了比较多的隐式操作,比如运行时类型检查,运行时数组越界检查,甚至是 GC 等。这些都是开销,比如 C++编译器就会做很多这方面的工作,如 virtual 函数,多态的 vtable ,异常调用等。 对于是否有足够优秀的优化器,这里的内容相当多且复杂,就比如你的编译器支持循环的向量化优化,那么同样的程序,性能就完全不一样了。当然还有很多函数内以函数间的分析与优化,都会对性能产生不同的影响,这方面可以对比 llvm 与 gcc 。 对于编译型语言和解析型语言,差别在于前者生成本地代码,而后者生成解析器可以识别的代码,因此这里涉及从目标代码到本地代码转换的过程,你可以简单地认为解析器就是一个 while+switch 。可能看似性能差别应该不大,但是结果往往是相差一个数量级左右,看你实现地好坏了,或许直接用汇编写个解析器,性能会更好点,应该很少有人会这么做,因为现在大家完全可以用即时编译来弥补一定的性能差距。 |
82
cutepig49 2016-01-07 17:28:33 +08:00
如果完全做的是同一件事,那么结果当然应该是完全相同。
问题是在于,不同的编程语言里,看似一样的操作,其实所做的并不是同一件事。有的会添加数组越界检查,有的有 GC ,还有的数字类型天然与大数字无缝转换。 这些都与最单纯的 C 做的不是同一件事,并且这些多出来的工作代价还都不小。 |
83
Alphabetcn 2016-01-07 17:54:24 +08:00
任何事情都是要代价的,而且代价不是恒定的,更何况途径方式不一样
|
84
davidjqq19 2016-01-07 18:01:04 +08:00
@airqj 这个比喻好,有的是隔着 T 恤挠,有的是隔着棉衣,有的是隔着很多层棉衣。
|
85
wizardforcel 2016-01-07 21:23:36 +08:00
首先就是编译或者解释的执行方式。解释里面有带 jit 和不带 jit 的,又不一样。编译里面有用 gc 的,有不用 gc 而用 arc 的,有完全是手动管理内存的。然后生成的机器码长短也不一样,我不知道你玩过反汇编没有, vb6 的机器码就很长很长, c++好点,但是编译器插了很多构造析构的指令, c 算是可以一一对应上的。各种情况很复杂很复杂。
|
86
BeanMrx 2016-01-09 08:07:12 +08:00 via Android
@temberature 如果这个解释器,编译器翻译足牛的确没差异!但是实际这个问题是,语言的易用性,编译器可实现性,硬件的优化限制之间的均衡!明显的例子 C 可以指定哪个分支可能性更大辅导 CPU 指令预测,但这个增加了使用者负担,所以 Java 没有这个语义了,那么 CPU 就按照指令返回跳转认为是循环预取循环体,向下跳转预取第一分支,预测错了就要冲刷流水线!这种台相关的例子不
|