0

以下哪个代码片段会导致最少的开销(或者 IL 是否相同)?我的程序可能会生成巨大的锯齿状数组,具体取决于我提供给它的约束公式的数量。我想限制为 decimal[][] 对象分配不必要的内存:

decimal[][] originalFormTableau = CreateOriginalFormTableau();
decimal[][] standardFormTableau = InsertSlackVariables(originalFormTableau);
this.Engine = new SimplexEngine(standardFormTableau, normalizationThreshold);

或者

this.Engine = new SimplexEngine(
    InsertSlackVariables(
    CreateOriginalFormTableau()),
    normalizationThreshold);

或任何其他建议(也许使用 using ref 代替?)

4

2 回答 2

4

分解它们:

//we start with a space on the stack from a local or parameter
//holding whatever normalizationThreshold is
//1. Create a space on the stack to hold a decimal[][]
//Call CreateOriginalFormTableau() method
//assign result to that space.
decimal[][] originalFormTableau = CreateOriginalFormTableau();
//2. Create a space on the stack to hold a decimal[][]
//Call InsertSlackVariables() method, passing in the first decimal[][]
//assign result to that second space.
decimal[][] standardFormTableau = InsertSlackVariables(originalFormTableau);
//3. Call the Engine setter with the second space or assign it to the Engine field.
this.Engine = new SimplexEngine(standardFormTableau, normalizationThreshold)

对比:

//we start with a space on the stack from a local or parameter
//holding whatever normalizationThreshold is
//1. Create a space on the stack to hold a decimal[][]
//Call CreateOriginalFormTableau() method
//assign result to that space.
//2. Create a space on the stack to hold a decimal[][]
//Call InsertSlackVariables() method, passing in the first decimal[][]
//assign result to that second space.
//3. Call the Engine setter with the second space or assign it to the Engine field.
this.Engine = new SimplexEngine(
  InsertSlackVariables(
  CreateOriginalFormTableau()),
  normalizationThreshold);

它们是完全相同的代码,但一个版本为另一个未命名的部分命名。

它们在调试版本中的性能可能略有不同,尽管我对此表示怀疑(有时发布版本会重用堆栈槽,而调试版本则不会,因此即使在他们获胜后,您也可以检查范围内的变量' 不会再次使用,但很可能它也不会重用未命名的插槽,即使它确实有所作为,影响也会很小)。

于 2012-09-05T09:53:06.000 回答
3

为科学做了测试:

版本 1

public void Test1()
{
    decimal[][] originalFormTableau = CreateOriginalFormTableau();
    decimal[][] standardFormTableau = InsertSlackVariables(originalFormTableau);
    this.Engine = new SimplexEngine(standardFormTableau, normalizationThreshold);
}

输出:

.method public hidebysig instance void Test1() cil managed
{
    .maxstack 4
    .locals init (
        [0] valuetype [mscorlib]System.Decimal[][] originalFormTableau,
        [1] valuetype [mscorlib]System.Decimal[][] standardFormTableau)
    L_0000: ldarg.0 
    L_0001: call instance valuetype [mscorlib]System.Decimal[][] ConsoleApplication2.Class2::CreateOriginalFormTableau()
    L_0006: stloc.0 
    L_0007: ldarg.0 
    L_0008: ldloc.0 
    L_0009: call instance valuetype [mscorlib]System.Decimal[][] ConsoleApplication2.Class2::InsertSlackVariables(valuetype [mscorlib]System.Decimal[][])
    L_000e: stloc.1 
    L_000f: ldarg.0 
    L_0010: ldloc.1 
    L_0011: ldarg.0 
    L_0012: call instance object ConsoleApplication2.Class2::get_normalizationThreshold()
    L_0017: newobj instance void ConsoleApplication2.SimplexEngine::.ctor(valuetype [mscorlib]System.Decimal[][], object)
    L_001c: call instance void ConsoleApplication2.Class2::set_Engine(class ConsoleApplication2.SimplexEngine)
    L_0021: ret 
}

版本 2

this.Engine = new SimplexEngine(
    InsertSlackVariables(
    CreateOriginalFormTableau()),
    normalizationThreshold);

输出:

.method public hidebysig instance void Test2() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldarg.0 
    L_0002: ldarg.0 
    L_0003: call instance valuetype [mscorlib]System.Decimal[][] ConsoleApplication2.Class2::CreateOriginalFormTableau()
    L_0008: call instance valuetype [mscorlib]System.Decimal[][] ConsoleApplication2.Class2::InsertSlackVariables(valuetype [mscorlib]System.Decimal[][])
    L_000d: ldarg.0 
    L_000e: call instance object ConsoleApplication2.Class2::get_normalizationThreshold()
    L_0013: newobj instance void ConsoleApplication2.SimplexEngine::.ctor(valuetype [mscorlib]System.Decimal[][], object)
    L_0018: call instance void ConsoleApplication2.Class2::set_Engine(class ConsoleApplication2.SimplexEngine)
    L_001d: ret 
}

在发行版中编译,优化开启。我不得不说,由于方法中没有重用局部变量,我相信编译器会重写Test1Test2. 不知何故,它没有。所以我想Test2会稍微快一点,尽管它可能不是以可衡量的方式。

因此,除非您正在搜索微秒优化,否则请选择最易读的优化。

于 2012-09-05T10:02:31.793 回答