在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?
当前回答
C的设计者们已经做出了取舍。也就是说,他们决定把速度放在安全之上。C不会
检查数组下标边界 检查未初始化的变量值 检查内存泄漏 检查空指针解引用
当你索引到一个数组时,在Java中,它接受虚拟机中的一些方法调用,绑定检查和其他健全检查。这是有效的,绝对没问题,因为它在应有的地方增加了安全性。但是在C语言中,即使是非常微不足道的东西也不会被放在安全的地方。例如,C不要求memcpy检查要复制的区域是否重叠。它并不是一种用于编写大型商业应用程序的语言。
但是这些设计决策并不是C语言中的bug。它们是被设计出来的,因为它允许编译器和库编写者从计算机中获得每一点性能。下面是C语言的精神——C语言的基本原理文档是这样解释的:
C code can be non-portable. Although it strove to give programmers the opportunity to write truly portable programs, the Committee did not want to force programmers into writing portably, to preclude the use of C as a ``high-level assembler'': the ability to write machine-specific code is one of the strengths of C. Keep the spirit of C. The Committee kept as a major goal to preserve the traditional spirit of C. There are many facets of the spirit of C, but the essence is a community sentiment of the underlying principles upon which the C language is based. Some of the facets of the spirit of C can be summarized in phrases like Trust the programmer. Don't prevent the programmer from doing what needs to be done. Keep the language small and simple. Provide only one way to do an operation. Make it fast, even if it is not guaranteed to be portable. The last proverb needs a little explanation. The potential for efficient code generation is one of the most important strengths of C. To help ensure that no code explosion occurs for what appears to be a very simple operation, many operations are defined to be how the target machine's hardware does it rather than by a general abstract rule. An example of this willingness to live with what the machine does can be seen in the rules that govern the widening of char objects for use in expressions: whether the values of char objects widen to signed or unsigned quantities typically depends on which byte operation is more efficient on the target machine.
其他回答
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语言可用的库和编译器比新语言要老得多。你可能认为这会让它们变慢,但事实恰恰相反。
这些库是在处理能力和内存非常重要的时候编写的。它们必须写得非常高效,才能发挥作用。C编译器的开发人员也花了很长时间为不同的处理器进行各种巧妙的优化。C语言的成熟和广泛采用使得它比同时期的其他语言具有显著的优势。它还使C语言在速度上比那些不像C语言那样强调原始性能的新工具更有优势。
只需在您的IDE中逐步检查机器代码,您就会看到为什么它更快(如果它更快的话)。它省去了很多手把手的环节。很有可能你的Cxx也会被告知不要使用,在这种情况下,它应该是相同的。
编译器优化被高估了,就像几乎所有关于语言速度的看法一样。
优化生成的代码只会对热点代码产生影响,也就是说,没有函数调用(显式或隐式)的紧凑算法。在其他地方,收效甚微。
这都是时间和努力的问题。
给予无限的时间和努力:
汇编程序比用C语言编写的程序要快。 C程序将比用c++编写的程序更快。
固定的:给定一定的时间和努力:
c++程序比用C编写的程序要快。 C语言的程序比用汇编语言编写的程序要快。
为什么?因为你做的抽象越多,你就可以花更多的时间来优化真正重要的代码关键部分。这里的几个假设是,一个开发人员对这三种语言都有同样的能力,你不关心二进制大小、内存使用情况等。
每种抽象都有其成本效益,但应该使代码更容易、更快地编写。
不要轻信别人的话,看看在代码的任何性能关键部分,C语言和你选择的语言的反汇编。我认为你可以在Visual Studio运行时的反汇编窗口中看到已分解的. net。如果Java使用windbg有点棘手,应该是可能的,尽管如果你用。net来做,许多问题将是相同的。
如果没有必要的话,我不喜欢用C来编写,但我认为,这些回答中吹捧除C之外其他语言的速度的许多主张可以放在一边,只需用C和您选择的高级语言分解相同的例程,特别是如果涉及大量数据(这在性能关键型应用程序中很常见)。Fortran在其专业领域可能是个例外,不知道。它比C高吗?
第一次比较JITed代码和本地代码时,我解决了。net代码是否能与C代码运行得相当的所有问题。额外的抽象层次和所有的安全检查都带来了巨大的成本。同样的成本可能也适用于Java,但不要相信我的话,在性能至关重要的地方尝试一下。(有没有人足够了解JITed Java来在内存中找到一个编译过的过程?这当然是可能的)
推荐文章
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 在SQL Server上使用varchar(MAX) vs TEXT
- c++中size_t和int的区别是什么?
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- 在C和c++中静态变量存储在哪里?
- 是什么导致JNI调用变慢?
- 检查属性是否有属性
- errno线程安全吗?
- 如何快速清除JavaScript对象?
- 如何在C程序中获取当前目录?
- 互斥实例/教程?
- 如何添加一个'或'条件在#ifdef
- extern关键字对C函数的影响
- Node.js vs .Net性能
- 如果使用if-return-return或if-else-return?