我正在编写一个图像处理程序来执行视频帧的实时处理.它是在C#中使用包装OpenCV库dll(非托管C++)的Emgu.CV库(C#).现在我必须编写自己的特殊算法,它需要尽可能快.
哪个算法的实现速度更快?
在C#中编写'不安全'函数
将该函数添加到OpenCV库并通过Emgu.CV调用它
我猜C#unsafe比较慢,因为它是通过JIT编译器,但差异是否显着?
编辑:
在VS2008下编译为.NET 3.5
它需要尽可能快
然后你问错了问题.
在汇编程序中对其进行编码,为您支持的每个重要架构变体提供不同的版本.
使用优秀的C++编译器的输出作为指导,因为它可能知道一些你不知道的技巧.但是你可能会想到一些改进,因为C++并不一定向编译器传达可能对优化有用的所有信息.例如,C++没有C99关键字限制.虽然在这种特殊情况下,许多C++编译器(包括MSVC)现在都支持它,所以尽可能使用它.
当然,如果你的意思是"我希望它快速,但不要超出C#或C++的范围",那么答案是不同的;-)
在很多情况下,我希望C#至少可以达到类似外观C++的性能.我当然假设程序运行的时间足够长,以至于JIT本身所用的时间是无关紧要的,但是如果你正在处理很多视频,那么这似乎很可能.但是我也希望有一些东西,如果你在不安全的C#中执行它们,将远远慢于C++中的等价物.我不知道它们是什么,因为我对JIT的所有经验都是用Java而不是CLR.在C++中也可能存在速度较慢的事情,例如,如果您的算法将任何调用重新调用到C#代码中.
不幸的是,确定它的接近程度的唯一方法是编写它们并测试它们,哪种方式错过了编写C++版本是一堆额外的努力.但是,您可能会通过黑客攻击一些近似于您想要执行的处理的快速代码来获得一个粗略的想法,而不必完成所有操作或正确执行.如果算法要遍历所有像素并且每个像素执行一些FP操作,那么将粗略的基准测试混合在一起需要花费半个小时.
通常我建议不要开始思考"这需要尽可能快".要求应该是可以实现的,并且根据定义"尽可能X"只能实现边界化.要求也应该是可测试的,并且"尽可能的X"是不可测试的,除非您以某种方式知道理论最大值.一个更友好的要求是"这需要在这样的速度CPU上实时处理这种分辨率的视频帧",或"这需要比我们的主要竞争对手的产品更快".如果C#版本这样做,可以考虑用户设置中的意外小问题,然后完成工作.
它取决于算法,实现,C++编译器和JIT编译器.我猜在大多数情况下C++实现会更快.但这可能会改变.
JIT编译器可以针对运行代码的平台优化代码,而不是像C++编译器那样对代码可能运行的所有平台的平均代码进行优化.这是JIT编译器的新版本越来越擅长并且在某些情况下可能给JITted代码带来优势.所以答案并不像你想象的那么清楚.例如,新的Java热点编译器可以很好地完成这项工作.
托管代码可能比C++做得更好的其他情况是需要分配和释放大量小对象的地方..net运行时预分配了可以重用的大块内存,因此每次需要分配内存时都不需要调用os.
我不确定不安全的C#运行速度比普通C#快得多.你也得试试这个.
如果您想知道什么是适合您情况的最佳解决方案,您必须同时尝试并测量差异.我不认为会有更多
语言没有"速度".这取决于编译器和代码.可以用任何语言编写低效的代码,无论源语言如何,聪明的编译器都会生成接近最优的代码.
C#和C++之间唯一真正不可避免的性能因素是C#应用程序必须在启动时执行更多操作(加载.NET框架以及JIT某些代码),所以在所有条件相同的情况下,它们的启动速度会慢一些.在那之后,它取决于,并且没有一个根本原因,为什么一种语言必须总是比另一种语言更快.
我也不知道为什么不安全的C#应该比安全更快.一般来说,安全性很好,因为它允许编译器做出更强大的假设,因此安全性可能更快.但同样,这取决于您正在编译的代码,您正在使用的编译器以及其他十几个因素.
简而言之,放弃你可以衡量一种语言表现的想法.你不能.语言永远不会"快"或慢".它没有速度.
C#通常比C++慢.托管代码中存在运行时检查.毕竟,这些是使它得到管理的原因.例如,C++不必检查是否已超出数组的边界.
根据我的经验,使用固定内存有很大帮助..NET 4.0中有一个新的System.IO.UnmanagedMemoryAccessor类,可能在将来有所帮助.