哪个更快 - C# 不安全代码或原始 C++
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/280624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Which is faster - C# unsafe code or raw C++
提问by geometrikal
I'm writing an image processing program to perform real time processing of video frames. It's in C# using the Emgu.CV library (C#) that wraps the OpenCV library dll (unmanaged C++). Now I have to write my own special algorithm and it needs to be as fast as possible.
我正在编写一个图像处理程序来执行视频帧的实时处理。它在 C# 中使用 Emgu.CV 库 (C#) 封装 OpenCV 库 dll(非托管 C++)。现在我必须编写我自己的特殊算法,它需要尽可能快。
Which will be a faster implementation of the algorithm?
哪个将是算法的更快实现?
Writing an 'unsafe' function in C#
Adding the function to the OpenCV library and calling it through Emgu.CV
用 C# 编写一个“不安全”的函数
将函数加入OpenCV库并通过Emgu.CV调用
I'm guessing C# unsafe is slower because it goes throught the JIT compiler, but would the difference be significant?
我猜 C# unsafe 比较慢,因为它通过 JIT 编译器,但差异会很大吗?
Edit:
编辑:
Compiled for .NET 3.5 under VS2008
VS2008下为.NET 3.5编译
采纳答案by Steve Jessop
it needs to be as fast as possible
它需要尽可能快
Then you're asking the wrong question.
那你问错了问题。
Code it in assembler, with different versions for each significant architecture variant you support.
在汇编程序中对其进行编码,为您支持的每个重要架构变体使用不同的版本。
Use as a guide the output from a good C++ compiler with optimisation, because it probably knows some tricks that you don't. But you'll probably be able to think of some improvements, because C++ doesn't necessarily convey to the compiler all information that might be useful for optimisation. For example, C++ doesn't have the C99 keyword restrict. Although in that particular case many C++ compilers (including MSVC) do now support it, so use it where possible.
使用经过优化的优秀 C++ 编译器的输出作为指南,因为它可能知道一些您不知道的技巧。但是您可能会想到一些改进,因为 C++ 不一定会将所有可能对优化有用的信息传达给编译器。例如,C++ 没有 C99 关键字限制。尽管在这种特殊情况下,许多 C++ 编译器(包括 MSVC)现在都支持它,因此请尽可能使用它。
Of course if you mean, "I want it to be fast, but not to the extent of going outside C# or C++", then the answer's different ;-)
当然,如果您的意思是“我希望它运行得很快,但不能超出 C# 或 C++”,那么答案就不一样了 ;-)
I would expect C# to at least approach the performance of similar-looking C++ in a lot of cases. I assume of course that the program will be running long enough that the time the JIT itself takes is irrelevant, but if you're processing much video then that seems likely. But I'd also expect there to be certain things which if you do them in unsafe C#, will be far slower than the equivalent thing in C++. I don't know what they are, because all my experience of JITs is in Java rather than CLR. There might also be things which are slower in C++, for instance if your algorithm makes any calls back into C# code.
在很多情况下,我希望 C# 至少可以接近外观相似的 C++ 的性能。我当然假设该程序将运行足够长的时间,以至于 JIT 本身所花费的时间无关紧要,但如果您正在处理大量视频,那么这似乎很可能。但我也希望有些事情如果你在不安全的 C# 中做,会比 C++ 中的等价事情慢得多。我不知道它们是什么,因为我所有的 JIT 经验都是用 Java 而不是 CLR。在 C++ 中也可能存在较慢的事情,例如,如果您的算法将任何调用返回到 C# 代码中。
Unfortunately the only way to be sure how close it is is to write both and test them, which kind of misses the point that writing the C++ version is a bunch of extra effort. However, you might be able to get a rough idea by hacking some quick code which approximates the processing you want to do, without necessarily doing all of it or getting it right. If you algorithm is going to loop over all the pixels and do a few FP ops per pixel, then hacking together a rough benchmark should take all of half an hour.
不幸的是,确定两者之间的接近程度的唯一方法是同时编写并测试它们,这种方法忽略了编写 C++ 版本需要付出额外努力这一点。但是,您可以通过编写一些近似于您想要执行的处理的快速代码来获得一个粗略的想法,而不必全部完成或正确处理。如果您的算法要遍历所有像素并为每个像素执行一些 FP 操作,那么编写一个粗略的基准测试应该需要半个小时。
Usually I would advise against starting out thinking "this needs to be as fast as possible". Requirements should be achievable, and by definition "as X as possible" is only borderline achievable. Requirements should also be testable, and "as X as possible" isn't testable unless you somehow know a theoretical maximum. A more friendly requirement is "this needs to process video frames of such-and-such resolution in real time on such-and-such a speed CPU", or "this needs to be faster than our main competitor's product". If the C# version does that, with a bit to spare to account for unexpected minor issues in the user's setup, then job done.
通常我会建议不要开始思考“这需要尽可能快”。要求应该是可以实现的,根据定义,“尽可能 X”只是可以实现的边界。需求也应该是可测试的,除非您以某种方式知道理论最大值,否则“尽可能 X”是不可测试的。更友好的要求是“这需要在某某速度的CPU上实时处理某某分辨率的视频帧”,或者“这需要比我们主要竞争对手的产品更快”。如果 C# 版本做到了这一点,在用户设置中考虑到一些意外的小问题,那么工作就完成了。
回答by Mendelt
It depends on the algorithm, the implementation, the C++ compiler and the JIT compiler. I guess in most cases the C++ implementation will be faster. But this may change.
这取决于算法、实现、C++ 编译器和 JIT 编译器。我想在大多数情况下,C++ 实现会更快。但这可能会改变。
The JIT compiler can optimize your code for the platform your code is running on instead of an average for all the platforms your code might run on as the C++ compiler does. This is something newer versions of the JIT compiler are increasingly good at and may in some cases give JITted code an advantage. So the answer is not as clear as you might expect. The new Java hotspot compiler does this very well for example.
JIT 编译器可以针对您的代码运行的平台优化您的代码,而不是像 C++ 编译器那样针对您的代码可能运行的所有平台进行平均。这是 JIT 编译器的新版本越来越擅长的东西,在某些情况下可能会给 JITted 代码带来优势。所以答案并不像你想象的那么清楚。例如,新的 Java 热点编译器在这方面做得很好。
Other situations where managed code may do better than C++ is where you need to allocate and deallocate lots of small objects. The .net runtime preallocates large chunks of memory that can be reused so it doesn't need to call into the os every time you need to allocate memory.
托管代码可能比 C++ 做得更好的其他情况是您需要分配和释放大量小对象。.net 运行时预先分配了可重用的大块内存,因此不需要每次需要分配内存时都调用操作系统。
I'm not sure unsafe C# runs much faster than normal C#. You'll have to try this too.
我不确定不安全的 C# 比普通的 C# 运行得快得多。你也得试试这个。
If you want to know what's the best solution for your situation you'll have to try both and measure the difference. I dont think there will be more than
如果您想知道什么是最适合您的情况的解决方案,则必须同时尝试两者并衡量差异。我不认为会有更多
回答by jalf
Languages don't have a "speed". It depends on the compiler and the code. It's possible to write inefficient code in any language, and a clever compiler will generate near-optimal code no matter the language of the source.
语言没有“速度”。这取决于编译器和代码。用任何语言编写低效的代码都是可能的,无论源语言是什么,聪明的编译器都会生成近乎最优的代码。
The only really unavoidable factor in performance between C# and C++ is that C# apps have to do more at startup (load the .NET framework and perhaps JIT some code), so all things being equal, they will launch a bit slower. After that, it depends, and there's no fundamental reason why one language must always be faster than another.
C# 和 C++ 之间唯一真正不可避免的性能因素是 C# 应用程序在启动时必须做更多的事情(加载 .NET 框架和 JIT 一些代码),所以在所有条件相同的情况下,它们的启动速度会慢一些。在那之后,这取决于,并且没有根本原因为什么一种语言必须总是比另一种更快。
I'm also not aware of any reasons why unsafe C# should be faster than safe. In general, safe is good because it allows the compiler to make some much stronger assumptions, and so safe mightbe faster. But again, it depends on the code you're compiling, the compiler you're using and a dozen other factors.
我也不知道为什么不安全的 C# 应该比安全更快的任何原因。一般来说,安全是好的,因为它允许编译器做出一些更强大的假设,所以安全可能更快。但同样,这取决于您正在编译的代码、您正在使用的编译器以及许多其他因素。
In short, give up on the idea that you can measure the performance of a language. You can't. A language is never "fast" or slow". It doesn't have a speed.
简而言之,放弃可以衡量语言性能的想法。你不能。语言从来没有“快”或“慢”之分。它没有速度。
回答by Dave
Running on the CPU is always going to be faster than running on a VM on the CPU. I can't believe people are trying to argue otherwise.
在 CPU 上运行总是比在 CPU 上的 VM 上运行要快。我不敢相信人们正试图以其他方式争论。
For example, we have some fairly heavy image processing work on our web server that's queued up. Initially to get it working, we used PHP's GD functions.
例如,我们在排队的 Web 服务器上有一些相当繁重的图像处理工作。最初为了让它工作,我们使用了 PHP 的 GD 函数。
They were slow as hell. We rewrote the functionality we needed in C++.
他们慢得要命。我们在 C++ 中重写了我们需要的功能。
回答by Thomas Bratt
C# is typically slower than C++. There are runtime checks in managed code. These are what make it managed, after all. C++ doesn't have to check whether the bounds of an array have been exceeded for example.
C# 通常比 C++ 慢。托管代码中有运行时检查。毕竟,这些是让它得以管理的原因。例如,C++ 不必检查是否超出了数组的边界。
From my experience, using fixed memory helps a lot. There is a new System.IO.UnmanagedMemoryAccessorclass in .NET 4.0 which may help in the future.
根据我的经验,使用固定内存有很大帮助。.NET 4.0 中有一个新的System.IO.UnmanagedMemoryAccessor类,将来可能会有所帮助。
回答by thAAAnos
If you are going to implement your algorithm in a standard way I think it's irrelevant. But some languages have bindings to apis or libraries that can give you a non standart boost.
如果您打算以标准方式实现您的算法,我认为这无关紧要。但是有些语言绑定了 apis 或库,可以给你一个非标准的提升。
Consider if you can use GPU processing - nvidia and ati provide the CUDA and CTM frameworks and there is an ongoing standarization effort from the khronos group (openGL). A hunch tells me also that amd will add at least one streaming processor core in their future chips. So I think there is quite a promise in that area.
Try to see if you can exploit SSE instructions, there are libraries around -most in C++ or C- that provide handy apis, check Intel's site for handy optimized libraries I do recall "Intel Performance Primitives" and a "Math Kernel".
考虑一下您是否可以使用 GPU 处理——nvidia 和 ati 提供了 CUDA 和 CTM 框架,并且 khronos 组 (openGL) 正在进行标准化工作。一种预感还告诉我,amd 将在他们未来的芯片中添加至少一个流处理器核心。所以我认为在那个领域有很大的希望。
尝试看看您是否可以利用 SSE 指令,周围有一些库 - 大多数在 C++ 或 C 中 - 提供方便的 api,查看英特尔的站点以获取方便的优化库,我确实记得“英特尔性能原语”和“数学内核”。
But on the politics side, do incorporate your algorithm in OpenCV so others may benefit too.
但在政治方面,请务必将您的算法纳入 OpenCV,以便其他人也可能受益。
回答by Tom Barta
If you know your environment and you use a good compiler (for video processing on windows, Intel C++ Compiler is probably the best choice), C++ will beat C# hands-down for several reasons:
如果您了解自己的环境并且使用了良好的编译器(对于 Windows 上的视频处理,英特尔 C++ 编译器可能是最佳选择),C++ 将击败 C#,原因如下:
- The C++ runtime environment has no intrinsic runtime checks (the downside being that you have free reign to blow yourself up). The C# runtime environment is going to have some sanity checking going on, at least initially.
- C++ compilers are built for optimizing code. While it's theoretically possible to implement a C# JIT compiler using all of the optimizing voodo that ICC (or GCC) uses, it's doubtful that Microsoft's JIT will reliably do better. Even if the JIT compiler has runtime statistics, that's still not as good as profile-guided optimization in either ICC or GCC.
- A C++ environment allows you to control your memory model much better. If your application gets to the point of thrashing the data cache or fragmenting the heap, you'll really appreciate the extra control over allocation. Heck, if you can avoid dynamic allocations, you're already much better off (hint: the running time of
malloc()
or any other dynamic allocator is nondeterministic, and almost all non-native languages force heavier heap usage, and thus heavier allocation).
- C++ 运行时环境没有内在的运行时检查(缺点是您可以自由支配自己)。C# 运行时环境将进行一些完整性检查,至少在最初阶段是这样。
- C++ 编译器是为优化代码而构建的。虽然理论上可以使用 ICC(或 GCC)使用的所有优化伏都来实现 C# JIT 编译器,但微软的 JIT 能否可靠地做得更好仍值得怀疑。即使 JIT 编译器具有运行时统计信息,它仍然不如 ICC 或 GCC 中的配置文件引导优化好。
- C++ 环境允许您更好地控制您的内存模型。如果您的应用程序达到了对数据缓存进行颠簸或对堆进行碎片化的程度,您将非常感谢对分配的额外控制。哎呀,如果你能避免动态分配,你已经好多了(提示:
malloc()
或任何其他动态分配器的运行时间是不确定的,几乎所有非本地语言都强制使用更重的堆,因此分配更重)。
If you use a poor compiler, or if you can't target a good chipset, all bets are off.
如果您使用糟糕的编译器,或者如果您不能针对一个好的芯片组,那么所有的赌注都将落空。
回答by Peter Tate
I'm a little late in responding but I can give you some anecdotal experience. We had some matrix multiplication routines that were originally coded in C# using pointers and unsafe code. This proved to be a bottleneck in our application and we then used pinning+P/Invoke to call into a C++ version of the Matrix multiplication routine and got a factor of 2 improvement. This was a while ago with .NET 1.1, so things might be better now. As others point out, this provesnothing, but it was an interesting exercise.
我的回复有点晚,但我可以给你一些轶事经验。我们有一些矩阵乘法例程,它们最初是使用指针和不安全代码在 C# 中编码的。这被证明是我们应用程序中的一个瓶颈,然后我们使用 pinning+P/Invoke 来调用矩阵乘法例程的 C++ 版本,并获得了 2 倍的改进。这是 .NET 1.1 的前一段时间,所以现在情况可能会好一些。正如其他人指出的那样,这并不能证明什么,但这是一个有趣的练习。
I also agree with thAAAnos, if you algorithm really has to be "as fast as possible" leverage IPL or, if you must, consider a GPU implementation.
我也同意 thAAAnos,如果你的算法真的必须“尽可能快”地利用 IPL,或者如果你必须考虑 GPU 实现。
回答by user25967
To be honest, what language you write it in is not nearly as important as what algorithms you use (IMO, anyway). Maybe by going to native code you mightmake your application faster, but it might also make it slower--it'd depend on the compiler, how the programs are written, what sort of interop costs you'd incur if you're using a mixed environment, etc. You can't really say without profiling it. (and, for that matter, have you profiled your application? Do you actually know where it's spending time?)
老实说,你用什么语言编写它并不像你使用什么算法那么重要(无论如何,IMO)。也许通过使用本机代码,您可以使您的应用程序更快,但也可能使其更慢——这取决于编译器、程序的编写方式、如果您使用,您会产生什么样的互操作成本混合环境等。如果不对其进行分析,您就不能真正说出来。(并且,就此而言,您是否已对您的应用程序进行了概要分析?您真的知道它在哪里花费时间吗?)
A better algorithm is completely independent of the language you choose.
更好的算法完全独立于您选择的语言。
回答by Simon Miller
It's a battle that will rage on forever. C versus C++ versus C# versus whatever. In C#, the notion of unsafe is to unlock "dangerous" operations. ie, the use of pointers, and being able to cast to void pointers etc, as you can in C and C++. Very dangerous, and very powerful! But defeating what C# was based upon.
这是一场将永远持续下去的战斗。C 与 C++ 与 C# 与其他任何东西。在 C# 中,不安全的概念是解锁“危险”操作。即,使用指针,并能够转换为空指针等,就像在 C 和 C++ 中一样。很危险,也很强大!但是打败了 C# 的基础。
You'll find that nowadays, Microsoft has made strides in the direction of performance, especially since the release of .NET, and the next version of .NET will actually support inline methods, as you can with C++. This will increase performance for very specific situations. I hate that it's not going to be a c# feature, but a nasty attribute the compiler picks up on - but you can't have it all.
您会发现,如今,Microsoft 在性能方向上取得了长足的进步,尤其是自 .NET 发布以来,并且 .NET 的下一个版本实际上将支持内联方法,就像使用 C++ 一样。这将提高非常特定情况下的性能。我讨厌它不会是 ac# 功能,而是编译器会选择的一个讨厌的属性 - 但你不能拥有它。
Personally, I'm writing a game with C# and managed DirectX (why not XNA?? beyond the scope of this post). I'm using unsafe code in graphical situations, which brings about a nod in the direction of what others have said.
就个人而言,我正在用 C# 编写游戏并管理 DirectX(为什么不使用 XNA??超出了本文的范围)。我在图形情况下使用了不安全的代码,这让我对其他人所说的话表示赞同。
It's only because pixel access is rediculously slow with GDI++ that I was driven to look for alternatives. But on the whole, the c# compiler is pretty damned good, and for code comparisons (you can find articles) you'll find the performance is very comparable to c++. That's not to say there isn't a better way to write the code.
只是因为 GDI++ 的像素访问速度非常慢,我才被迫寻找替代方案。但总的来说,c# 编译器非常好,对于代码比较(您可以找到文章),您会发现性能与 c++ 非常相似。这并不是说没有更好的方法来编写代码。
At the end of the day, I personally see C, C++, and C# as about the same speed when executing. It's just that in some painful situations where you want to work really closely with the underlying hardware or very close to those pixels, that you'll find noticeable advantage to the C/C++ crowd.
归根结底,我个人认为 C、C++ 和 C# 在执行时的速度大致相同。只是在一些痛苦的情况下,您希望与底层硬件非常紧密地工作或非常接近那些像素,您会发现 C/C++ 人群的明显优势。
But for business, and most things nowadays, C# is a real contender, and staying within the "safe" environment is definitely a bonus.
When stepping outside, you can get most things done with unsafe code, as I have - and boy, have I gone to some extremes! But was it worth it? Probably not. I personally wonder if I should have thought more along the lines of time-critical code in C++, and all the Object Oriented safe stuff in C#. But I have better performance than I thought I'd get!
但是对于商业和当今的大多数事情,C# 是一个真正的竞争者,并且保持在“安全”环境中绝对是一个奖励。
走出去时,您可以使用不安全的代码完成大部分事情,就像我一样 - 男孩,我是否走到了一些极端!但值得吗?可能不是。我个人想知道我是否应该更多地考虑 C++ 中的时间关键代码以及 C# 中所有面向对象的安全内容。但我的表现比我想象的要好!
So long as you're careful with the amount of interop calls you're making, you can get the best of both worlds. I've personally avoided that, but I don't know to what cost.
只要您小心处理所发出的互操作调用的数量,就可以两全其美。我个人避免了这种情况,但我不知道要付出什么代价。
So an approach I've not tried, but would love to hear adventures in, in actually using C++.NET to develop a library in - would that be any faster than c#'s unsafe for these special graphical situations? How would that compare to native C++ compiled code? Now there's a question!
所以一种我没有尝试过但很想听听冒险的方法,在实际使用 C++.NET 开发一个库时 - 对于这些特殊的图形情况,这会比 c# 的不安全更快吗?与本机 C++ 编译代码相比如何?现在有一个问题!
Hmm..
唔..