我很久以前用普通的C开始,然后转移到C ++,现在我面临着C ++ / CLI。作为一个表演怪胎,我总是试图将最后一滴性能压缩到每一行代码。我目前正处于一个主要在VB.Net中完成的项目(简单性,资源可用性等),但有几点对性能非常敏感,我打算用C ++ / CLI做这些部分。但是,只有一小部分可以从托管代码中取出,而其余部分需要保持管理。问题是,与C#或VB.Net相比,编写C ++ / CLI管理函数是否可以获得任何性能提升?从我从一直阅读的文档中可以理解,唯一的优势似乎是托管/非托管的thunking更轻。是这样的吗?因为我甚至无法将句柄存储在非托管数组或结构中(我可以更快地操作),例如:
String ^ mystr = "Oh, my!";
Object ^ myarray[10];
myarray[0] = mystr; // Can't event be casted to void*, int, HANDLE...
// (however, handles do have a sizeof() == 4 in Win32)
// (I don't expect the handle to behave like a pointer; just stay as handle)
答案 0 :(得分:3)
我也是一个表演狂,我已经学会了
在我知道性能问题出现之前,我甚至不会问这个问题,
一旦我知道它们在哪里,我就不需要问了,因为我可以很容易地找到答案,因为a)所有编译语言都会生成我可以看到的汇编或中间语言,并且b)我可以运行10 ^ 6次,只需计时。
我的经验是存在多种性能问题,具有各种尺寸。首先,我解决了最简单/最大的问题。这使得其余的人占用了更多的时间,因此在下次通过时更容易找到。**
I keep doing tuning passes until I run out of performance problems I can fix. 到那时,代码可以比开始时更快。
**示例:假设程序需要10秒钟。假设有两个问题(直到你看起来都不知道),它们分别占50%和30%。你修复了第一个,时间下降到5秒。现在第二个问题是消耗60%,因为总时间减少了,因此更容易发现。修复它,时间下降到2秒 - 加速5倍。问题越多,可能的加速就越大。人们可能怀疑他们有如此大的问题,如果是这样,抽样会证明或反驳它。
答案 1 :(得分:3)
管理C ++ / CLI - 它被编译为与其他所有.net语言相同的MSIL。如果速度对你来说是王道,那么在本机dll中写下关键位并从你的vb.net应用程序中取消它(保持thunk数量下降你应该没问题。)
虽然tbh,id首先分析代码,看看这是否真的有必要,而不仅仅是过早的优化。无论如何,MSIL都可以被编译成本机代码 - 真正的问题是.net JITer是否与原生c / c ++编译器一样优化。
答案 2 :(得分:1)
C ++ / CLI编译成MSIL没有性能优势,就像C#和VB.NET一样。您可以在VB和C ++ / CLI中编写一些简单的测试函数,以便自己查看。
答案 3 :(得分:1)
顺便说一下,要将句柄存储在内存的非托管部分,我只需要使用GCHandle structure或gcroot。
答案 4 :(得分:0)
您可能会在C ++ / CLI中看到的唯一性能增益是混合本机代码和托管代码的位置。 C ++ / CLI允许您为性能关键的代码段调用本机方法,而且开销比VB.Net少。我不建议在本地和本地管理之间进行切换,因为仍然存在惩罚,但是可以接受将控制传递给本机代码以获得一大块与性能相关的代码。
答案 5 :(得分:0)
虽然C ++ / CLI编译器可能无法为直接转换代码提供更好的性能,但是有许多C ++功能可以在托管代码中提供巨大的性能优势。
一个很重要的是模板。为每个模板参数组合重新生成代码并进行独立优化。虽然.NET泛型通常会抑制最简单的内联,但转换为C ++ / CLI模板可以实现额外的优化机会,以及在任何其他.NET语言中没有等效的特化和编译时元程序。
答案 6 :(得分:0)
性能提升来自将非托管代码与托管程序集混合。 C ++ / cli使这很容易。尝试通过c#或vb.net使用pinvoke调用c ++ ...你要么必须在外部c调用中包装c ++,要么通过它的受损名称调用c ++。此外,您还可以从优化的Microsoft C ++编译器中获得相当好的性能。如果你不混合使用非托管代码,那么就没有性能提升,因为它像其他人提到的一样编译成MSIL。