在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?
当前回答
我还没有看到它,所以我要说:C往往更快,因为几乎所有其他东西都是用C写的。
Java是建立在C上的,Python是建立在C上的(或者Java,或者。net等等),Perl是等等。操作系统是用C写的,虚拟机是用C写的,编译器是用C写的,解释器是用C写的,有些东西仍然是用汇编语言写的,这往往更快。越来越多的东西是用别的东西写的,而这些东西本身就是用C写的。
您用其他语言(不是Assembly)编写的每个语句通常都在下面实现为C中的几个语句,这些语句被编译为本机机器代码。由于其他语言的存在往往是为了获得比C更高的抽象级别,因此C中所需的那些额外语句往往侧重于增加安全性、增加复杂性和提供错误处理。这些通常都是好事,但它们是有代价的,那就是速度和规模。
就我个人而言,我已经用几十种语言写过了,涵盖了大部分可用的范围,我个人也一直在寻找你暗示的魔法:
我怎样才能鱼与熊掌兼得呢?我如何在我最喜欢的语言中玩高级抽象,然后为了速度而降至C语言的细节?
经过几年的研究,我的答案是Python(在C上)。你可能想看看它。顺便说一下,您也可以从Python下拉到Assembly(从一个特殊的库中获得一些小小的帮助)。
另一方面,任何语言都可能编写出糟糕的代码。因此,C(或汇编)代码不会自动更快。同样,一些优化技巧可以使部分高级语言代码的性能水平接近原始c语言的性能水平。但是,对于大多数应用程序来说,程序的大部分时间都在等待人员或硬件,因此两者之间的差异实际上并不重要。
享受。
其他回答
实际上,在某些应用程序(数字)中,甚至C也可以被击败,我指的不是汇编语言,而是老的、经常被嘲笑的Fortran。原因是,Fortran保证没有指针别名。
主要的因素是它是一种静态类型的语言,可以编译为机器代码。此外,由于它是一种低级语言,它通常不会做任何您不让它做的事情。
这些是我想到的其他一些因素。
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语言比现代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/ c++编译器在所有平台上变得越来越普遍,这有点令人不安。您可以在平台之间进行交叉编译。这仍然不是一个到处运行的情况,你基本上是在指示编译器a针对编译器B编译相同的代码,不同的架构。
归根结底,C语言并不意味着容易理解或推理,这也是为什么它们被称为系统语言。他们出现在所有高层次抽象的废话之前。这也是为什么它们不用于前端web编程。他们只是不适合这项任务,他们的意思是解决传统语言工具无法解决的复杂问题。
这就是为什么你会得到一些疯狂的东西(微架构、驱动程序、量子物理、AAA游戏、操作系统),这些东西C和c++非常适合。速度和数据处理是主要领域。
使用现代优化编译器,纯C程序不太可能比编译后的。net代码快得多,如果有的话。通过像。net这样的框架为开发人员提供的生产力提高,您可以在一天内完成过去用普通c语言需要几周或几个月才能完成的工作。再加上与开发人员的工资相比,硬件成本低廉,用高级语言编写这些东西并以任何缓慢的速度抛出硬件要便宜得多。
The reason Jeff and Joel talk about C being the "real programmer" language is because there is no hand-holding in C. You must allocate your own memory, deallocate that memory, do your own bounds-checking, etc. There's no such thing as new object(); There's no garbage collection, classes, OOP, entity frameworks, LINQ, properties, attributes, fields, or anything like that. You have to know things like pointer arithmetic and how to dereference a pointer. And, for that matter, know and understand what a pointer is. You have to know what a stack frame is and what the instruction pointer is. You have to know the memory model of the CPU architecture you're working on. There is a lot of implicit understanding of the architecture of a microcomputer (usually the microcomputer you're working on) when programming in C that simply is not present nor necessary when programming in something like C# or Java. All of that information has been off-loaded to the compiler (or VM) programmer.