/clr 編譯時,受控函數會產生兩個入口點:
虛函數指標只能指向其中一個,編譯器需選擇預設入口。VS2003 一律選非受控;VS2005+ 若簽章含受控型別則選受控入口。跨入口呼叫會觸發受控/非受控轉換與參數複製,影響效能。
在函數宣告加上 __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 nv) { value = nv; }
};
class bubble2 : public bubbleBase {
public:
virtual int __clrcall getvalue() { return value; }
virtual void __clrcall setvalue(int nv) { value = nv; }
};
template void bubbleSort(int length) {
TimeSpan ts;
T* array1 = new T[ARRAY_SIZE];
for (int i=0; i0; --i) {
int test=0;
for (int j=0; j array1[j+1].getvalue()) {
int temp = array1[j].getvalue();
array1[j].setvalue(array1[j+1].getvalue());
array1[j+1].setvalue(temp);
test=1;
}
}
if (!test) break;
}
ts = TimeSpan::FromTicks(DateTime::Now.Ticks - ticks);
Console::WriteLine("BubbleSort {0} Items: {1} Ticks", ARRAY_SIZE, ts.Ticks);
delete[] array1;
}
int main(array^ args) {
bubbleSort(ARRAY_SIZE); // 無 __clrcall
bubbleSort(ARRAY_SIZE); // 有 __clrcall
return 0;
}
BubbleSort 1000 Items: 3281250 Ticks // bubble1
BubbleSort 1000 Items: 312500 Ticks // bubble2
加速約 10.5 倍。頻繁呼叫的虛函數、介面方法、委派目標均適用。
VC8.0 STL 預設啟用 _SECURE_SCL(迭代器邊界檢查),確認無緩衝區溢位風險時,定義 _SECURE_SCL=0 可進一步提升速度。
^, %, generic 等)。滿足上述條件即可放心加上 __clrcall 獲取效能紅利。