0
我想看看下面兩個簡單的遞歸函數將執行以及C#版本一個循環,所以我用ILSPY反編譯他們到C#。反編譯一個簡單的遞歸函數,並得到不必要代碼
let rec findPivot i =
if i = 0 then -1
else
if myArray.[i] > myArray.[i-1] then i - 1
else findPivot (i - 1)
let rec findTarget value i =
if (myArray.[i] > value) then i
else findTarget value (i - 1)
獲取:
internal static int [email protected](int[] myArray, int i)
{
while (i != 0)
{
if (myArray[i] > myArray[i - 1])
{
return i - 1;
}
int[] arg_22_0 = myArray; // useless
i--;
myArray = arg_22_0; // useless
}
return -1;
}
internal static int [email protected](int[] myArray, int value, int i)
{
while (myArray[i] <= value)
{
int[] arg_16_0 = myArray; // useless
int arg_14_0 = value; // useless
i--;
value = arg_14_0; // useless
myArray = arg_16_0; // useless
}
return i;
}
我很驚訝的是,F#編譯會產生這樣的亂碼。雖然它可能不會影響性能(JIT可能會進一步優化)。當代碼在系統中更加複雜和關鍵時,我仍然擔心性能問題。
關於爲什麼編譯器發出這樣的代碼的任何意見?
你真的看了IL而不是反編譯的代碼--F#編譯器實際上生成了很好的il,所以也許反編譯器轉換回C#生成奇數代碼。 – 2013-05-06 23:28:24
除了John Palmer的觀察,請記住,IL並不是實際運行的 - JIT編譯器可能會在轉換爲機器代碼時優化不需要的操作。我會分析代碼,看看你是否有實際的性能問題,而不是預先擔心它。 – kvb 2013-05-07 01:47:19
+1給kvb的觀點。檢查這個:https://gist.github.com/v2m/5530153 - JIT優化堆棧操作。 – desco 2013-05-07 03:56:35