在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?
当前回答
C语言速度很快,因为它是原生编译的低级语言。但是C不是最快的。递归斐波那契基准测试表明Rust、Crystal和Nim可以更快。
其他回答
有什么能阻止其他语言 能够编译成二进制文件 运行速度和C一样快?
没什么。像Java或。net语言这样的现代语言更多地面向程序员的生产力,而不是性能。现在硬件很便宜。此外,编译到中间表示提供了很多好处,如安全性,可移植性等。net CLR可以利用不同的硬件-例如,你不需要手动优化/重新编译程序来使用SSE指令集。
C语言并不总是更快。
C语言比现代Fortran语言慢。
在某些方面,C通常比Java慢。(特别是在JIT编译器对您的代码进行了测试之后)
C允许发生指针混叠,这意味着一些好的优化是不可能的。特别是当您有多个执行单元时,这将导致数据获取停滞。噢。
指针算术工作的假设确实会导致某些CPU系列(特别是PIC !)它曾经在x86上很差劲。
基本上,当你得到一个矢量单元,或者一个并行编译器,C语言很糟糕,而现代的Fortran运行得更快。
C程序员的一些技巧,比如thking(动态修改可执行文件)会导致CPU预取暂停。
明白我的意思了吗?
而我们的好朋友x86执行的指令集,如今与实际的CPU架构关系不大。影子寄存器,负载存储优化器,都在CPU中。所以C离虚拟金属很近。真正的金属,英特尔不会让你看到。(从历史上看,VLIW CPU有点破产,所以,也许这并不是那么糟糕。)
如果你在高性能DSP上用C编程(可能是TI DSP ?),编译器必须做一些棘手的事情,在多个并行执行单元之间展开C。因此,在这种情况下,C语言并不接近金属,但它接近编译器,它将进行整个程序优化。奇怪。
最后,一些cpu (www.ajile.com)在硬件中运行Java字节码。C将在该CPU上使用一个PITA。
如果你花了一个月的时间用C语言构建的程序只需要0.05秒,而我花了一天的时间用Java写同样的程序,只需要0.10秒,那么C语言真的更快吗?
但是回答你的问题,编写良好的C代码通常会比其他语言编写的代码运行得更快,因为编写良好的C代码的一部分包括在接近机器的级别上进行手动优化。
尽管编译器确实非常聪明,但它们还不能创造性地提出与手工按摩算法竞争的代码(假设“手”属于一个优秀的C程序员)。
编辑:
很多评论都是这样的:“我用C语言编写,我不考虑优化。”
举个具体的例子:
在Delphi中我可以这样写:
function RemoveAllAFromB(a, b: string): string;
var
before, after :string;
begin
Result := b;
if 0 < Pos(a,b) then begin
before := Copy(b,1,Pos(a,b)-Length(a));
after := Copy(b,Pos(a,b)+Length(a),Length(b));
Result := before + after;
Result := RemoveAllAFromB(a,Result); //recursive
end;
end;
用C语言写:
char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
for (j = 0; j < len2; j++) {
if (s1[i] == s2[j]) {
break;
}
}
if (j == len2) { /* s1[i] is not found in s2 */
*result = s1[i];
result++; /* assuming your result array is long enough */
}
}
但是C版本中有多少优化呢?我们在实现方面做了很多我在Delphi版本中没有考虑到的决定。字符串是如何实现的?在特尔斐我看不出来。在C语言中,我已经决定它将是一个指向ASCII整数数组的指针,我们称之为字符。在C语言中,我们每次测试一个字符的存在性。在Delphi中,我使用Pos。
这只是一个小例子。在一个大型程序中,C程序员必须对每几行代码做出这类低级决策。它加起来就是一个手工制作、手工优化的可执行文件。
不要轻信别人的话,看看在代码的任何性能关键部分,C语言和你选择的语言的反汇编。我认为你可以在Visual Studio运行时的反汇编窗口中看到已分解的. net。如果Java使用windbg有点棘手,应该是可能的,尽管如果你用。net来做,许多问题将是相同的。
如果没有必要的话,我不喜欢用C来编写,但我认为,这些回答中吹捧除C之外其他语言的速度的许多主张可以放在一边,只需用C和您选择的高级语言分解相同的例程,特别是如果涉及大量数据(这在性能关键型应用程序中很常见)。Fortran在其专业领域可能是个例外,不知道。它比C高吗?
第一次比较JITed代码和本地代码时,我解决了。net代码是否能与C代码运行得相当的所有问题。额外的抽象层次和所有的安全检查都带来了巨大的成本。同样的成本可能也适用于Java,但不要相信我的话,在性能至关重要的地方尝试一下。(有没有人足够了解JITed Java来在内存中找到一个编译过的过程?这当然是可能的)
我认为没有人提到这样一个事实,即在C编译器上投入的精力比任何其他编译器都要多,也许Java是例外。
由于前面提到的许多原因,C是非常可优化的——几乎比任何其他语言都要多。因此,如果在其他语言编译器上投入同样的精力,C可能仍然会名列前茅。
I think there is at least one candidate language that with effort could be optimized better than C and thus we could see implementations that produce faster binaries. I'm thinking of digital mars D because the creator took care to build a language that could potentially be better optimized than C. There may be other languages that have this possibility. However I cannot imagine that any language will have compilers more than just a few percent faster than the best C compilers. I would love to be wrong.
我认为真正的“唾手可得的果实”将是那些被设计为易于人类优化的语言。一个熟练的程序员可以让任何语言运行得更快——但有时你不得不做一些荒谬的事情或使用不自然的结构来实现这一点。尽管这总是需要付出努力,但一种好的语言应该产生相对快速的代码,而不必纠结于程序究竟是如何编写的。
It's also important (at least to me) that the worst case code tends to be fast. There are numerous "proofs" on the web that Java is as fast or faster than C, but that is based on cherry picking examples. I'm not big fan of C, but I know that ANYTHING I write in C is going to run well. With Java it will "probably" run within 15% of the speed, usually within 25% but in some cases it can be far worse. Any cases where it's just as fast or within a couple of percent are usually due to most of the time being spent in the library code which is heavily optimized C anyway.