在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?
当前回答
我认为没有人提到这样一个事实,即在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.
其他回答
如果你花了一个月的时间用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语言可用的库和编译器比新语言要老得多。你可能认为这会让它们变慢,但事实恰恰相反。
这些库是在处理能力和内存非常重要的时候编写的。它们必须写得非常高效,才能发挥作用。C编译器的开发人员也花了很长时间为不同的处理器进行各种巧妙的优化。C语言的成熟和广泛采用使得它比同时期的其他语言具有显著的优势。它还使C语言在速度上比那些不像C语言那样强调原始性能的新工具更有优势。
只需在您的IDE中逐步检查机器代码,您就会看到为什么它更快(如果它更快的话)。它省去了很多手把手的环节。很有可能你的Cxx也会被告知不要使用,在这种情况下,它应该是相同的。
编译器优化被高估了,就像几乎所有关于语言速度的看法一样。
优化生成的代码只会对热点代码产生影响,也就是说,没有函数调用(显式或隐式)的紧凑算法。在其他地方,收效甚微。
有什么能阻止其他语言 能够编译成二进制文件 运行速度和C一样快?
没什么。像Java或。net语言这样的现代语言更多地面向程序员的生产力,而不是性能。现在硬件很便宜。此外,编译到中间表示提供了很多好处,如安全性,可移植性等。net CLR可以利用不同的硬件-例如,你不需要手动优化/重新编译程序来使用SSE指令集。
甚至C和c++之间的差异有时也会很大。
当你为一个对象分配内存,调用构造函数,在字边界上对齐内存等等,程序最终会经历很多开销,这些开销都是从程序员那里抽象出来的。
C迫使您查看程序所做的每一件事,通常是非常精细的细节。这使得编写执行大量与当前目标无关的任务的代码变得更加困难(尽管并非完全不可能)。
因此,例如在BASIC程序中,你可以使用INPUT关键字从STDIN读取字符串并自动为其变量分配内存,在C中,程序员通常已经分配了内存,并可以控制诸如程序是否阻塞I/O,以及它是否在获得所需信息后停止读取输入或继续读取字符到行尾等事情。
C also performs a lot less error-checking than other languages, presuming the programmer knows what they're doing. So whereas in PHP if you declare a string $myStr = getInput(); and go on to reference $myStr[20], but the input was only 10 characters long, PHP will catch this and safely return to you a blank string. C assumes that you've either allocated enough memory to hold data past the end of the string or that you know what information comes after the string and are trying to reference that instead. These small factors have a huge impact on overhead in aggregate.