在听StackOverflow播客的时候,经常有人说“真正的程序员”是用C语言编写的,而C语言的速度要快得多,因为它“接近机器”。把前面的断言留到另一篇文章,C有什么特别之处,使它比其他语言更快?或者换句话说:什么能阻止其他语言编译成二进制代码,使其运行速度与C语言一样快?
当前回答
实际上,在某些应用程序(数字)中,甚至C也可以被击败,我指的不是汇编语言,而是老的、经常被嘲笑的Fortran。原因是,Fortran保证没有指针别名。
其他回答
这不是语言的问题,而是工具和库的问题。C语言可用的库和编译器比新语言要老得多。你可能认为这会让它们变慢,但事实恰恰相反。
这些库是在处理能力和内存非常重要的时候编写的。它们必须写得非常高效,才能发挥作用。C编译器的开发人员也花了很长时间为不同的处理器进行各种巧妙的优化。C语言的成熟和广泛采用使得它比同时期的其他语言具有显著的优势。它还使C语言在速度上比那些不像C语言那样强调原始性能的新工具更有优势。
这实际上是一个长期存在的谎言。虽然C程序确实经常更快,但情况并非总是如此,特别是当C程序员不太擅长它的时候。
人们往往会忘记的一个明显的漏洞是,当程序必须为某种IO阻塞时,比如任何GUI程序中的用户输入。在这些情况下,使用什么语言并不重要,因为您受到数据传入速度的限制,而不是处理数据的速度。在这种情况下,不管你使用的是C、Java、c#甚至Perl;你不能比数据进入的速度更快。
The other major thing is that using garbage collection and not using proper pointers allows the virtual machine to make a number of optimizations not available in other languages. For instance, the JVM is capable of moving objects around on the heap to defragment it. This makes future allocations much faster since the next index can simply be used rather than looking it up in a table. Modern JVMs also don't have to actually deallocate memory; instead, they just move the live objects around when they GC and the spent memory from the dead objects is recovered essentially for free.
This also brings up an interesting point about C and even more so in C++. There is something of a design philosophy of "If you don't need it, you don't pay for it." The problem is that if you do want it, you end up paying through the nose for it. For instance, the vtable implementation in Java tends to be a lot better than C++ implementations, so virtual function calls are a lot faster. On the other hand, you have no choice but to use virtual functions in Java and they still cost something, but in programs that use a lot of virtual functions, the reduced cost adds up.
The fastest running code would be carefully hand crafted machine code. Assembler will be almost as good. Both are very low level and it takes a lot of writing code to do things. C is a little above assembler. You still have the ability to control things at a very low level in the actual machine, but there is enough abstraction make writing it faster and easier then assembler. Other languages such as C# and JAVA are even more abstract. While Assembler and machine code are called low level languages, C# and JAVA (and many others) are called high level languages. C is sometimes called a middle level language.
我认为没有人提到这样一个事实,即在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程序不太可能比编译后的。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.