Generally, C# and Java can be just as fast or faster because the JIT compiler -- a compiler that compiles your IL the first time it's executed -- can make optimizations that a C++ compiled program cannot because it can query the machine. It can determine if the machine is Intel or AMD; Pentium 4, Core Solo, or Core Duo; or if supports SSE4, etc.
一个 C + + 程序必须事先进行编译,通常需要进行混合优化,这样它才能在所有机器上运行良好,但是对于单个配置(即处理器、指令集和其他硬件) ,它的优化程度还不够。
此外,某些语言特性允许 C # 和 Java 中的编译器对代码做出假设,从而允许它优化掉某些对 C/C + + 编译器来说不安全的部分。当您访问指针时,会有很多不安全的优化。
Java 和 C # 也可以比 C + + 更有效地进行堆分配,因为垃圾收集器和代码之间的抽象层允许它一次完成所有的堆压缩(这是一个相当昂贵的操作)。
现在我不能代表 Java 说下一点,但是我知道,例如,当 C # 知道方法体为空时,它实际上会删除方法和方法调用。它将在整个代码中使用这种逻辑。
因此,正如您所看到的,有很多原因可以解释为什么某些 C # 或 Java 实现会更快。
现在这一切都说明,特定的优化可以在 C + + 中进行,这将吹走任何你可以用 C # 做的事情,特别是在图形领域和任何时候你接近硬件。指针在这里能创造奇迹。
So depending on what you're writing I would go with one or the other. But if you're writing something that isn't hardware dependent (driver, video game, etc), I wouldn't worry about the performance of C# (again can't speak about Java). It'll do just fine.
On top of what some others have said, from my understanding .NET and Java are better at memory allocation. E.g. they can compact memory as it gets fragmented while C++ cannot (natively, but it can if you're using a clever garbage collector).
For many practical purposes, allocation/deallocation-intensive algorithms implemented in garbage collected languages can actually be faster than their equivalents using manual heap allocation. A major reason for this is that the garbage collector allows the runtime system to amortize allocation and deallocation operations in a potentially advantageous fashion.
也就是说,我已经编写了大量的 C # 和 C + + ,并运行了大量的基准测试。根据我的经验,C + + 比 C # 快得多,有两个方面: (1)如果你用 C # 写了一些代码,把它移植到 C + + ,本地代码 往往会更快。多快?虽然变化很大,但速度提高100% 并不罕见。(2)在某些情况下,垃圾收集可以 非常严重减慢托管应用程序的速度。那个。NET CLR 在处理大堆(比如,> 2GB)方面做得很糟糕,最终可能会在 GC 中花费大量时间——即使是在中间生命周期对象很少(甚至没有)的应用程序中。
当然,在我遇到的大多数情况下,托管语言都足够快,远远不够,而维护和编码对 C + + 额外性能的折衷并不好。
Some good answers here about the specific question you asked. I'd like to step back and look at the bigger picture.
Keep in mind that your user's perception of the speed of the software you write is affected by many other factors than just how well the codegen optimizes. Here are some examples:
是的,一个 C + + 程序在任何给定的情况下都能比 C # 更快(非常重要?)但是 C # 中的程序通常会和 C + + 中的“幼稚”实现一样快或者更快,而且 C + + 中的优化版本将花费更长的时间来开发,并且仍然可能以非常小的差距击败 C # 版本。真的值得吗?
你必须逐一回答这个问题。
也就是说,我是 C + + 的长期粉丝,我认为它是一种极具表现力和强大功能的语言——有时被低估了。但是在许多“现实生活”问题中(对我个人来说,这意味着“我得到报酬来解决的那种”) ,C # 将更快更安全地完成工作。
The biggest penalty you pay? Many .NET and Java programs are memory hogs. I have seen .NET and Java apps take "hundreds" of megabytes of memory, when C++ programs of similar complexity barely scratch the "tens" of MBs.
当然, C # (或 Java, 或 VB)通常比 C + + 更快地产生可行和健壮的解决方案(如果只是因为 C + + 有复杂的语义, 和 C++标准程式库, 虽然有趣和强大, 是相当差的标准库的全范围相比, 从。NET 或 Java) ,所以通常情况下,C + + 和。NET 或 Java JIT 对于大多数用户来说是不可见的,对于那些关键的二进制文件,你仍然可以从 C # 或 Java 调用 C + + 处理(即使这种本地调用本身可能非常昂贵) ..。
C + + 元编程
请注意,通常您将 C + + 运行时代码与 C # 或 Java 中的等效代码进行比较。但是 C + + 有一个特性可以胜过 Java/C # 开箱即用,那就是模板元编程: 代码处理将在编译时完成(因此大大增加了编译时间) ,导致运行时为零(或几乎为零)。
我已经看到了现实生活中对此的影响(我只玩概念,但到那时,不同之处在于 JIT 的执行时间是几秒钟,而 C + + 的执行时间是 零) ,但是值得一提的是,与此同时,模板元编程并不是微不足道的..。
编辑2011-06-10: 在 C + + 中,对类型的处理是在编译时完成的,这意味着生成调用非通用代码的通用代码(例如,一个从字符串到类型 T 的通用解析器,调用标准库 API 来识别类型 T,并使解析器容易被用户扩展)是非常容易和非常有效的,而 Java 或 C # 中的等价物在编写时最多是痛苦的,即使在编译时知道类型,在运行时也总是更慢和解析,这意味着你唯一的 希望 < i > 是 JIT 内联整个事情。
去年的趋势是,Java 服务器应用程序注定要取代旧的 C + + 服务器应用程序,因为 Java 有很多框架/工具,并且易于维护、部署等等。.
直到最近几个月低延迟问题出现。然后,Java 服务器应用程序,无论我们熟练的 Java 团队尝试了多少优化,都干净利落地输掉了与老式的、没有真正优化的 C + + 服务器的竞赛。
Currently, the decision is to keep the Java servers for common use where performance while still important, is not concerned by the low-latency target, and aggressively optimize the already faster C++ server applications for low-latency and ultra-low-latency needs.
结论
Nothing is as simple as expected.
Java,甚至更多的 C # ,都是很酷的语言,拥有大量的标准库和框架,在这些语言中你可以快速编码,并且很快就会有结果。
But when you need raw power, powerful and systematic optimizations, strong compiler support, powerful language features and absolute safety, Java and C# make it difficult to win the last missing but critical percents of quality you need to remain above the competition.
It's as if you needed less time and less experienced developers in C#/Java than in C++ to produce average quality code, but in the other hand, the moment you needed excellent to perfect quality code, it was suddenly easier and faster to get the results right in C++.
当然,这是我个人的看法,也许仅限于我们的具体需要。
但是,无论是在 GUI 团队还是在服务器端团队中,这仍然是今天发生的事情。
当然,如果有新的事情发生,我会更新这篇文章。
编辑(2011-06-22)
“我们发现,在性能方面,C + + 赢得了
但是,它也需要最广泛的
tuning efforts, many of which were done at a level of sophistication
普通程序员无法使用的。
“ Facebook 的流行语是‘ 合理编写的 C + + 代码运行得很快,’,它强调了在优化 PHP 和 Java 代码方面所付出的巨大努力。自相矛盾的是,C + + 代码比其他语言更难写,但是 efficient code is a lot easier [to write in C++ than in other languages].”
– Herb Sutter at 建造, quoting 返回文章页面【 Andrei Alexandrescu 】亚历山大 · 雷斯库译者:
If you're a Java/C# programmer learning C++, you'll be tempted to keep thinking in terms of Java/C# and translate verbatim to C++ syntax. In that case, you only get the earlier mentioned benefits of native code vs. interpreted/JIT. To get the biggest performance gain in C++ vs. Java/C#, you have to learn to think in C++ and design code specifically to exploit the strengths of C++.
针对特定 CPU 优化的编译通常被高估了。只需用 C + + 编写一个程序,用奔腾 PRO 进行优化编译,然后在奔腾4上运行。然后为奔腾4重新编译并进行优化。我花了好几个下午的时间和几个节目一起做这件事。一般结果? ?性能提升通常小于2-3% 。因此,理论上的 JIT 优势几乎为零。大多数性能差异只能在使用标量数据处理特性时才能观察到,这些特性最终将需要手动微调才能实现最大的性能。这种类型的优化执行起来既缓慢又昂贵,因此有时不适合 JIT。
当然他用的是可用的更低的
水平库做到这一点,但这是
还有很多工作要做,你能打电话
什么是剩下的 STL 程序? 我不知道
think so, I think he kept the
向量类,它最终是
从来没有问题,他保持了发现
function. Pretty much everything else
消失了。
所以,没错,你绝对可以打败
雷蒙德可以让他的程序运行
甚至更快。
有趣的是,解析
file as reported by both programs
internal timers is about the same --
每个30毫秒,差别在于
开销。
For me the bottom line is that it took 6 revisions for the unmanaged version to beat the managed version that was a simple port of the original unmanaged code. If you need every last bit of performance (and have the time and expertise to get it), you'll have to go unmanaged, but for me, I'll take the order of magnitude advantage I have on the first versions over the 33% I gain if I try 6 times.
One of the most significant JIT optimizations is method inlining. Java can even inline virtual methods if it can guarantee runtime correctness. This kind of optimization usually cannot be performed by standard static compilers because it needs whole-program analysis, which is hard because of separate compilation (in contrast, JIT has all the program available to it). Method inlining improves other optimizations, giving larger code blocks to optimize.
Standard memory allocation in Java/C# is also faster, and deallocation (GC) is not much slower, but only less deterministic.
Please note that the speed of javascript varries a lot depending on what browser is executing it. The same is true for Flash and Silverlight because these plugins run in the same process as the hosting browser. But the Roozz plugin run standard .exe files, which run in their own process, thus the speed is not influenced by the hosting browser.
使用 C # 和 Java,你需要为你所得到的付出代价(更快的编码、自动内存管理、大型库等等)。但你没有太多的空间来讨价还价的细节: 采取完整的一揽子或没有。
Even if those languages can optimize some code to execute faster than compiled code, the whole approach is (IMHO) inefficient. Imagine driving every day 5 miles to your workplace, with a truck! Its comfortable, it feels good, you are safe (extreme crumple zone) and after you step on the gas for some time, it will even be as fast as a standard car! Why don't we all have a truck to drive to work? ;)
在 C + + 中,你得到的是你花钱买的东西,而不是更多,而不是更少。
引用比雅尼·斯特劳斯特鲁普: “ c + + 是我最喜欢的垃圾收集语言,因为它产生的垃圾太少了。”
链接文本
对于任何需要大量速度的东西,JVM 只调用 C + + 实现,所以问题更多的是它们的库有多好,而不是 JVM 对于大多数与操作系统相关的东西有多好。
Garbage collection cuts your memory in half, but using some of the fancier STL and Boost features will have the same effect but with many times the bug potential.
如果您只是在一个有许多类的大型项目中使用 C + + 库和它的许多高级特性,那么您可能会比使用 JVM 慢一些。只是更容易出错。
然而,C + + 的好处在于它允许您优化自己,否则您将被困在编译器/jvm 所做的工作中。如果你制作自己的容器,编写自己的对齐的内存管理,使用 SIMD,到处进行汇编,你至少可以比大多数 C + + 编译器自己的速度提高2-4倍。对于某些操作,16x-32x。这是使用相同的算法,如果你使用更好的算法和并行化,增加可以是戏剧性的,有时比常用的方法快几千倍。
A very short answer: Given a fixed budget you will achieve better performing java application than a C++ application (ROI considerations) In addition Java platform has more decent profilers, that will help you pinpoint your hotspots more quickly
Go read about HP Labs' 发电机, an interpreter for PA-8000 that runs on PA-8000, and often runs programs faster than they do natively. Then it won't seem at all surprising!
You might get short bursts when Java or CLR is faster than C++, but overall the performance is worse for the life of the application:
看看 www.codeproject.com/kb/dotnet/runtimeperformance.aspx 的结果吧。
Orion Adrian ,让我把你的帖子倒过来看看你的评论是多么没有根据,因为 C + + 也可以说很多东西。告诉 Java/C # 编译器优化去除空函数确实让你听起来像是我的优化专家,因为 a)为什么一个真正的程序应该包含空函数,除了非常糟糕的遗留代码,b)这真的不是黑色和前沿优化。
除了这句话,您还公然抨击了指针,但是 Java 和 C # 中的对象不是基本上像 C + + 指针一样工作吗?它们可以不重叠吗?它们可能不是无效的吗?C (和大多数 C + + 实现)都有限制关键字,都有值类型,C + + 有引用到值和非空保证。Java 和 C # 提供什么?
>>>>>>>>>>
一般来说,C 和 C + + 可以同样快或者更快,因为 AOT 编译器——一个在部署之前编译你的代码的编译器,一劳永逸地,在你的高内存许多核心构建服务器上——可以进行 C # 编译程序所不能进行的优化,因为它有大量的时间来这样做。编译器可以判断机器是 Intel 还是 AMD; Pentium 4、 Core Solo 还是 Core Duo; 或者是否支持 SSE4等等,如果你的编译器不支持运行时分派,你可以通过部署一些专门的二进制文件来解决这个问题。
一个 C # 程序通常是在运行的时候编译的,这样它在所有机器上都能很好地运行,但是对于单个配置(例如处理器、指令集、其他硬件)来说,它并没有得到足够的优化,而且它首先要花一些时间在 must上。诸如循环裂变、循环反转、自动矢量化、整体程序优化、模板扩展、首次公开募股等等,这些特性都很难在不惹恼终端用户的情况下完全解决。
此外,某些特定的语言特性允许 C + + 或 C 中的编译器对代码做出假设,从而允许它对 Java/C # 编译器不安全的特定部分进行优化。当您不能访问泛型的完整类型 id 或者一个有保证的程序流时,就会有很多不安全的优化。
同样,C + + 和 C 只需要一个寄存器增量就可以同时进行多个堆栈分配,这对于垃圾收集器和代码之间的抽象层来说,肯定比 Java 和 C # 分配更有效率。
Now I can't speak for Java on this next point, but I know that C++ compilers for example will actually remove methods and method calls when it knows the body of the method is empty, it will eliminate common subexpressions, it may try and retry to find optimal register usage, it does not enforce bounds checking, it will autovectorize loops and inner loops and will invert inner to outer, it moves conditionals out of loops, it splits and unsplits loops. It will expand std::vector into native zero overhead arrays as you'd do the C way. It will do inter procedural optimmizations. It will construct return values directly at the caller site. It will fold and propagate expressions. It will reorder data into a cache friendly manner. It will do jump threading. It lets you write compile time ray tracers with zero runtime overhead. It will make very expensive graph based optimizations. It will do strength reduction, were it replaces certain codes with syntactically totally unequal but semantically equivalent code (the old "xor foo, foo" is just the simplest, though outdated optimization of such kind). If you kindly ask it, you may omit IEEE floating point standards and enable even more optimizations like floating point operand re-ordering. After it has massaged and massacred your code, it might repeat the whole process, because often, certain optimizations lay the foundation for even certainer optimizations. It might also just retry with shuffled parameters and see how the other variant scores in its internal ranking. And it will use this kind of logic throughout your code.
因此,正如您所看到的,有很多原因可以解释为什么某些 C + + 或 C 实现会更快。
尽管如此,很多优化都可以在 C + + 中完成,这些优化会让你无法用 C # 完成任何事情,特别是在数字处理、实时和接近金属的领域,但不仅仅是这些领域。你甚至不需要触摸一个单指针就可以走很长的路。
所以根据你写的东西,我会选择其中一个。但是,如果您正在编写一些不依赖于硬件的东西(驱动程序、视频游戏等) ,我不会担心 C # 的性能(同样不能谈论 Java)。没问题的。
My understanding is that C/C++ produces native code to run on a particular machine architecture. Conversely, languages like Java and C# run on top of a virtual machine which abstracts away the native architecture. Logically it would seem impossible for Java or C# to match the speed of C++ because of this intermediate step, however I've been told that the latest compilers ("hot spot") can attain this speed or even exceed it.
这不合逻辑。使用中间表示并不会降低性能。例如,LLVM-GCC 通过 LLVM IR (这是一个虚拟的无限寄存器机器)将 C 和 C + + 编译成本机代码,并获得了出色的性能(通常优于 GCC)。
具有 JIT 编译的虚拟机有助于运行时代码的生成(例如 System.Reflection.Emit on。NET) ,所以你可以用 C # 和 F # 这样的语言动态编译生成的代码,但是必须用 C 或 C + + 编写一个相对较慢的解释器。例如,实现正则表达式。
Parts of the virtual machine (e.g. the write barrier and allocator) are often written in hand-coded assembler because C and C++ do not generate fast enough code. If a program stresses these parts of a system then it could conceivably outperform anything that can be written in C or C++.
Dynamic linking of native code requires conformance to an ABI that can impede performance and obviates whole-program optimization whereas linking is typically deferred on VMs and can benefit from whole-program optimizations (like .NET's reified generics).
Hence template metaprogramming only works if the program is available at compile time which is often not the case, e.g. it is impossible to write a competitively performant regular expression library in vanilla C++ because it is incapable of run-time code generation (an important aspect of metaprogramming).
...playing with types is done at compile time...the equivalent in Java or C# is painful at best to write, and will always be slower and resolved at runtime even when the types are known at compile time.
In C#, that is only true of reference types and is not true for value types.
无论 JIT 优化如何,没有什么比直接指针访问内存更快的了... ... 如果你在内存中有连续的数据,通过 C + + 指针(例如 C 指针... ... 让我们给予凯撒应有的权限)访问它会比在 Java/C # 中快几倍。
Also worth noting that .NET does type specialization of generics across dynamically-linked libraries after linking whereas C++ cannot because templates must be resolved before linking. And obviously the big advantage generics have over templates is comprehensible error messages.
我不认为性能需要考虑有关处理速度的服务器这些天(在所有的多核处理器进入市场)。它应该根据内存使用情况进行更多的定义。这样 Java 就有点不利了。
但是所有的编程语言都适合不同的用途。这就是他们的竞争领域,每个赛段都有不同的赢家。
And I am sure Java will win in the long run for it continues development and competitiveness it shows in all the new features it produce.
我在这里找到了一个 链接,它将支持我为 Java 投票的理由