程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 托管C++中函數調用的雙重轉換

托管C++中函數調用的雙重轉換

編輯:關於C++
在VC.Net中使用默認設置/clr編譯時,一個托管函數會產生兩個入口點,一個是托管的,供托管代碼調用,另外一個是非托管的,供非托管代碼調用。但是函數地址,特別是虛函數指針只能有一個值,所以需要有一個默認的入口。

  非托管入口點可能是所有調用的默認入口(在 Visual Studio .NET2003 中,編譯器總是會選擇非托管入口,但是在Visual Studio 2005中,如果參數或者返回值中包含托管類型,那麼編譯器會選擇托管入口),而另外一個只是使用托管C++中的互操作功能對默認入口的調用。在一個托管函數被另一個托管函數調用的時候,這可能會造成不必要的托管/非托管上下文切換和參數/返回值的復制。如果函數不會被非托管代碼使用指針調用,那麼可以在聲明函數時用VC2005新增的__clrcall修飾符阻止編譯器生成兩個入口。

  現在用簡單的冒泡排序算法來比較一下使用__clrcall之後的性能改善程度。

using namespace System; 
#define ARRAY_SIZE 1000 

struct bubbleBase 
{ 
 int value; 
}; 
class bubble1:public bubbleBase 
{ 
public: 
 virtual int getvalue(){return value;} 
 virtual void setvalue(int newvalue){value=newvalue;} 
}; 
class bubble2:public bubbleBase 
{ 
public: 
 virtual int __clrcall getvalue(){return value;} 
 virtual void __clrcall setvalue(int newvalue){value=newvalue;} 
}; 
template<class T> 
void bubbleSort(int length) 
{ 
 TimeSpan ts; 
 T* array1=new T[ARRAY_SIZE]; 
 for (int i=0;i<ARRAY_SIZE ;i++) 
 { 
  array1[i].setvalue(ARRAY_SIZE-i-1); 
 } 
 Int64 ticks=DateTime::Now.Ticks; 
 int i, j,temp, test;  
 for(i = length - 1; i > 0; i--) 
 { 
  test=0; 
  for(j = 0; j < i; j++) 
  { 
   if(array1[j].getvalue() > array1[j+1].getvalue())  
   { 
    temp = array1[j].getvalue(); 
    array1[j].setvalue(array1[j+1].getvalue()); 
    array1[j+1] .setvalue(temp); 
    test=1; 
   } 
  }  
  if(test==0) break;  
 }  
 ts=TimeSpan::FromTicks(DateTime::Now.Ticks-ticks); 
 Console::WriteLine("BubbleSort {0} Items: {1}  Ticks", 
  ARRAY_SIZE, 
  ts.Ticks ); 
 delete array1; 
} 
int main(array<System::String ^> ^args) 
{ 
 bubbleSort<bubble1>(ARRAY_SIZE); 
 bubbleSort<bubble2>(ARRAY_SIZE); 
    return 0; 
} 

運行結果是

BubbleSort 1000 Items: 3281250 Ticks
  BubbleSort 1000 Items: 312500 Ticks

可以看到,__clrcall會大大加快在托管代碼中調用托管函數的速度。

順便說一下,在隨VC8.0發布的STL中增加了很多安全特性,但是這也會造成程序的運行速度減慢。如果你確認程序不會有緩沖區溢出或者內存越界訪問的問題,那麼可以把_SECURE_SCL定義成0來關掉這個特性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved