在 LeetCode 問題二 sum 中,我注意到當我用 return 陳述句在一行中初始化回傳的陣列時,如下所示:
return new int[2] { i, o };
代碼比這樣寫的要慢得多:
int[] returnArr = new int[2] { i, o };
return returnArr;
由于顯而易見的原因,單行回傳使用較少的記憶體,但速度非常慢。為什么?
回應時間:275ms
public class Solution
{
public int[] TwoSum(int[] nums, int target)
{
for (int i = 0; i < nums.Length; i )
{
for (int o = i 1; o < nums.Length; o )
{
if (nums[i] nums[o] == target)
{
return new int[2] {i, o};
}
}
}
return new int[0];
}
}
回應時間:181ms
public class Solution
{
public int[] TwoSum(int[] nums, int target)
{
for (int i = 0; i < nums.Length; i )
{
for (int o = i 1; o < nums.Length; o )
{
if (nums[i] nums[o] == target)
{
int[] returnArr = new int[2] { i, o };
return returnArr;
}
}
}
return new int[0];
}
}
uj5u.com熱心網友回復:
在 Release 模式下,兩個 TwoSum 方法的 IL 體是相同的;
IL_0014: ldc.i4.2
IL_0015: newarr [System.Runtime]System.Int32
IL_001a: dup
IL_001b: ldc.i4.0
IL_001c: ldloc.0
IL_001d: stelem.i4
IL_001e: dup
IL_001f: ldc.i4.1
IL_0020: ldloc.1
IL_0021: stelem.i4
IL_0022: ret
在除錯模式下,只有 2 個操作碼。例如,方法的 IL 主體;
IL_001c: ldc.i4.2
IL_001d: newarr [System.Runtime]System.Int32
IL_0022: dup
IL_0023: ldc.i4.0
IL_0024: ldloc.0
IL_0025: stelem.i4
IL_0026: dup
IL_0027: ldc.i4.1
IL_0028: ldloc.1
IL_0029: stelem.i4
IL_002a: stloc.3
IL_002b: br.s IL_0058
第二個例子;
IL_001c: ldc.i4.2
IL_001d: newarr [System.Runtime]System.Int32
IL_0022: dup
IL_0023: ldc.i4.0
IL_0024: ldloc.0
IL_0025: stelem.i4
IL_0026: dup
IL_0027: ldc.i4.1
IL_0028: ldloc.1
IL_0029: stelem.i4
IL_002a: stloc.3
IL_002b: ldloc.3 // Pushes local variable, returnArr to the 3rd index of the evaluation stack.
IL_002c: stloc.s 4 // Pops latest pushed value from evaluation stack
IL_002e: br.s IL_005c
在發布模式下,由于編譯器優化,沒有區別,所以應該沒有任何區別。在除錯模式下,第二個代碼將變數推入堆疊,然后再次將其彈出,因此無論如何它應該運行得更慢。
為了獲得更準確的結果,您應該使用 BenchmarkDotNet 等基準庫,并且應該運行基準方法數百萬或數十億次并獲得平均/平均時間。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493143.html
