在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?


当前回答

与其说C的速度快,不如说C的成本模型是透明的。如果一个C程序慢,它的慢是通过一个明显的方式:执行很多语句。与C语言中操作的代价相比,对对象(特别是反射)或字符串的高级操作可能具有不明显的代价。

标准ML(使用MLton编译器)和Objective Caml这两种语言通常编译成二进制文件的速度与C语言一样快。如果你检查一下基准测试游戏,你会发现对于一些基准测试,比如二叉树,OCaml版本比c更快(我没有找到任何MLton的条目)。但不要把枪战看得太严重;正如它所说的,它是一个游戏,结果通常反映了人们在调优代码上投入了多少精力。

其他回答

我知道很多人都说过这句话,但是:

C更快,因为它(为你)做的更少。

这不是语言的问题,而是工具和库的问题。C语言可用的库和编译器比新语言要老得多。你可能认为这会让它们变慢,但事实恰恰相反。

这些库是在处理能力和内存非常重要的时候编写的。它们必须写得非常高效,才能发挥作用。C编译器的开发人员也花了很长时间为不同的处理器进行各种巧妙的优化。C语言的成熟和广泛采用使得它比同时期的其他语言具有显著的优势。它还使C语言在速度上比那些不像C语言那样强调原始性能的新工具更有优势。

如果你花了一个月的时间用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程序员必须对每几行代码做出这类低级决策。它加起来就是一个手工制作、手工优化的可执行文件。

主要的因素是它是一种静态类型的语言,可以编译为机器代码。此外,由于它是一种低级语言,它通常不会做任何您不让它做的事情。

这些是我想到的其他一些因素。

Variables are not automatically initialized No bounds checking on arrays Unchecked pointer manipulation No integer overflow checking Statically-typed variables Function calls are static (unless you use function pointers) Compiler writers have had lots of time to improve the optimizing code. Also, people program in C for the purpose of getting the best performance, so there's pressure to optimize the code. Parts of the language specification are implementation-defined, so compilers are free to do things in the most optimal way

大多数静态类型语言的编译速度可以和C语言一样快,甚至比C语言更快,特别是如果它们可以假设C语言因为指针别名等原因而不能这样做的话。

我猜你忘了汇编语言也是一种语言:)

但是说真的,只有当程序员知道自己在做什么的时候,C程序才会更快。你可以很容易地编写一个C程序,它比用其他语言编写的程序运行得更慢。

C语言之所以更快,是因为它就是这样设计的。它允许你做很多“低级”的事情,帮助编译器优化代码。或者,我们可以说,你程序员负责优化代码。但这通常相当棘手,而且容易出错。

其他语言,就像前面提到的其他语言一样,更关注程序员的生产力。人们普遍认为程序员的时间比机器的时间要昂贵得多(即使在过去)。因此,尽量减少程序员花在编写和调试程序上的时间,而不是减少程序的运行时间,是很有意义的。为了做到这一点,您将牺牲一些可以使程序更快的事情,因为许多事情都是自动化的。