我想开发一些图像处理代码,我想知道在C ++和C#中开发它们之间是否存在很大差异?
是否有任何详细文档解释了在C#中实现哪些好处以及在C ++中实现什么是好的?
据我所知,由于C#代码在运行之前编译为机器代码(使用.NET CLR JIT编译器),如果在代码开发过程中,两种语言之间应该没有太大区别,你看看特定语言建议实现设计模式(例如,使用大量新的而不是使用固定数组)。
编辑: 还有一些其他参数我一开始并没有想到,但是当我读到一些答案时,我正在看现在: 1-这是一个高级项目,这意味着我可以要求用户拥有一台非常好的计算机(大量的内存和多核处理器) 2-我可以假设用户有一个非常好的图形卡,所以我可以使用它的GPU进行处理。 3-我认为WPF有利于这一发展(我是对的!)。是否有类似的C ++库?我曾与MFC合作,但我不确定在处理需要显示图像的项目时,MFC和WPF一样好,而且GUI非常重要。
答案 0 :(得分:5)
.NET IL被编译为机器代码,就像C ++一样。但几乎总是C ++代码会更快,因为:
在某些情况下,托管代码可能比非托管代码更快:
总结:如果执行速度很重要,请使用C ++。但是,正如Paint.NET所示,C#可以快速足够。还要考虑主要使用C#进行编码的选项,一旦您对某些重要函数的速度不满意,请在C++/CIL重新实现它,或使用P/Invoke调用优化函数。
答案 1 :(得分:3)
作为将图像处理库从C ++转换为C#并且完成基准测试的人,语言对你正在做的事情的速度几乎没有影响,更重要的是你正在使用的算法以及你正在使用的算法。操纵图像(即在Windows中使用位图上的锁定位)。我设法获得了显着的速度提升,因为我可以在C#中比在C ++中更容易编写更多的并行代码,而且不能仅仅使用Monitor.Wait(我承认我不是C ++线程专家,实际上我不是一个C ++线程业余爱好者)但是有很多选项可以轻松地并行化操作(在图形中非常内在),从C ++转换到C#时加速了大量的速度(加上只需要担心关于释放资源而不是记忆使生活变得更加轻松。显然,如果你对C ++非常熟悉,那么你可以用C ++编写更快的代码,但是你知道C ++和SIMD可以胜过C#编译器。我还应该注意到,我们从C ++转换为C#,假设我们丢失大约10%的速度,我们转换的原因是添加新功能的时间成本太高以至于重写为C#变得值得我们,最终产品最终更快只是一个奖励(现在我也应该提到原始库是在SIMD扩展之前编写的,其中添加到Visual C ++,因此使用它是原始库作者无法使用的)。
答案 2 :(得分:1)
虽然你认为.NET代码被JIT编译为机器代码是正确的,但你必须意识到你几乎无法控制这个过程。你没有选择目标指令集,而托管代码主张声称JIT编译是优越的,因为它可以使用每台机器上可用的最快指令集,事实是这还没有实现
结论:您可以使用SSE指令编写C ++代码,这些指令的运行速度比同一CPU上JIT生成的代码快4倍。
其他一些值得一提的事情:SIMD并行性比编写更容易编写,编译器更容易优化。 SIMD没有开销,但线程同步不是免费的。使用SIMD的隐藏陷阱较少,因此获得线性加速更加容易。多线程容易陷入缓存线共享和争用。托管语言让您无法控制虚假共享。
是的,C#可以更轻松地进行多线程处理。糟糕。 C ++使得正确执行多线程变得更加可行,并且您可以从调整单线程代码中获得足够的速度,甚至不需要处理线程的额外复杂性。
如果你决定优化自己,这里有一些技巧:(一旦你达到了预期的性能,就停在线上的任何一点,因为你应用的越多,你的代码就越复杂)
处理原始数据时,不要使用一些在一堆像素上添加间接和抽象的API。这不仅可以减慢你的速度,还会干扰下一堆改进。 (Kris alluded to LockBits
vs SetPixel
,原始图片访问的原生例程为GetDIBits
)
缓存调整。一种简单的方法是将最内层的循环展开16倍左右。然后反转循环嵌套顺序。这将导致处理数据的矩形块,这些块通常是相互依赖的,因此您可以为每个缓存填充多次访问每个数据块。但是,在此阶段使用缓存分析器是一种浪费。
使用SIMD。在每次循环迭代中处理4个或更多倍像素。轻松获胜。特别是因为你已经稍微展开了循环,那些相同的指令只是坐在那里乞求合并。但是,除非你摆脱抽象,否则无法完成。
现在使用缓存分析器。 SIMD提取与标量指令具有明显不同的特征,因此您应该在SIMD转换后执行此操作。
也许多线程。如果问题真的很大。请特别注意缓存行大小。并尝试永远不要写入其他线程也使用的数据。绝对不要从多个线程写入相同的数据。
答案 3 :(得分:0)
这取决于你对这两种语言有多好,如果你真的是图像处理编程或算法的专家,c ++将为你的优化提供更多的自由。但如果你不是那么专家,那就使用更高级别的语言来保护自己
答案 4 :(得分:0)
有几个因素需要考虑......
是否有任何您可能想要使用的库 - 如果存在并且它们是.Net则可能会影响您支持C#的决策。
然而,我认为可以肯定地说,大多数密集型数字应用程序(以及图像处理基本上是在2D矩阵上的数字密集型操作)将用本机代码编写。有一个非常好的例外 - 看看Paint.Net,它几乎完全用托管代码编写,并且具有出色的性能和功能(http://getpaint.net)。
您申请的目的是什么?如果它是一种“爱好”或学习练习,那么请选择您最开心的语言。如果它是商业应用程序,我会首先查看库选项。