我正在将C#的DLL编码为高性能模块,所以我使用C++ / CLI,因为在C#中很容易引用它并支持本机代码。
我在msdn上发现,使用#pragmamanaged(push,off)和#pragmamanaged(pop)可以使其中的代码编译为本机代码。
但是根据我的简单测试,结果显示出相反的结果。
这是使用Visual Studio 2012用/ clr编译的代码。
int clrloop()
{
for (int i = 0; i < 999999999; i++)
{
double test=9.999;
test=pow(test, 10);
}
return 0;
}
#pragma managed(push,off)
int loop()
{
for (int i = 0; i < 999999999; i++)
{
double test=9.999;
test=pow(test, 10);
}
return 0;
}
#pragma managed(pop)
int main(array<System::String ^> ^args)
{
int a=loop();
int b=clrloop();
return 0;
}
性能分析表明,非托管loop()的成本是clrloop()的两倍。
但是,如果将loop()放入不同的.cpp文件中,并使用/ clr设置此单个文件,并且不使用#pragmamanaged(push,off)进行任何操作,结果将达到预期的效果。
那么,此#pragma有什么问题?
最佳答案
我自己找到答案,所以我正在回答。
问题是由函数pow()引起的。
pow()所在的math.h仅包含而没有任何预处理程序指令,这意味着它只是按托管方式进行编译。
因此,非托管loop()将必须调用托管pow(),从而从托管main()变为非托管loop(),再到托管pow()的三级跳,并导致开销。
解决方案是用#pragmamanaged(push,off)和#pragmamanaged(pop)包含math.h。