简体   繁体   English

什么是实例化工作者变量的最有效方法

[英]Whats The Most Efficient Way To Instantiate Worker Variables

Should I instantiate my worker variables inside or outside my for loop 我应该在for循环内部还是外部实例化worker变量

Eg 例如

a) 一种)

bool b = default(bool);

for (int i = 0; i < MyCollection.Length; i++)
{
  b = false;

  foreach(object myObject in myObjectCollection)
  {
    if (object.Property == MyCollection[i].Property)
    {
      b = true;
      break;
    }
  }      

  if (b)
  {
    DoSomethingWith(MyCollection[i]);
  }
}

b) b)

for (int i = 0; i < MyCollection.Length; i++)
{
  bool b = default(bool);

  foreach(object myObject in myObjectCollection)
  {
    if (object.Property == MyCollection[i].Property)
    {
      b = true;
      break;
    }
  }      

  if (b)
  {
    DoSomethingWith(MyCollection[i]);
  }
}

EDIT: Seems universally agreed that there will be no difference where the IL is concerned. 编辑:似乎普遍同意,就IL而言,没有区别。 But for readability and clarity of scope... inside is better 但是为了可读性和范围的清晰...内部更好

内部看起来更干净,但与乔恩(Jon)一致,IL不变。

Previous answer deleted as I'd misread the code. 先前的答案已删除,因为我会误读代码。 (Using "default(bool)" anywhere is a bit odd, btw.) (顺便说一句,在任何地方使用“ default(bool)”有点奇怪。)

However, unless the variable is captured by a delegate etc, I'd expect them to either compile to IL which is effectively the same (in terms of both behaviour and performance). 但是,除非变量由委托等捕获,否则我希望它们可以编译为实际上相同的IL(就行为和性能而言)。

As ever, write the most readable code first. 与以往一样,请首先编写最易读的代码。 Micro-optimising things like this is asking for trouble. 像这样的微优化事情正在自找麻烦。 I agree with the others who have suggested that you restrict the scope of variables as much as you can - so if you need it after the loop, you haven't got any choice anyway; 我同意那些建议您尽可能限制变量范围的建议-因此,如果您在循环后需要它,那么您别无选择。 otherwise declare it inside. 否则在里面声明。

Okay, here's a test program: 好的,这是一个测试程序:

using System;

class Test
{
    static void Main() {}

    static void DeclareInside()
    {
        for (int i=0; i < 10; i++)
        {
            bool x = false;
            for (int j=5; j < 20; j++)
            {
                if (i == j)
                {
                    x = true;
                    break;
                }
                if (x)
                {
                    Console.WriteLine("Yes");
                }
            }
        }
    }

    static void DeclareOutside()
    {
        bool x;
        for (int i=0; i < 10; i++)
        {
            x = false;
            for (int j=5; j < 20; j++)
            {
                if (i == j)
                {
                    x = true;
                    break;
                }
                if (x)
                {
                    Console.WriteLine("Yes");
                }
            }
        }
    }
}

Generated IL (just csc Test.cs ): 生成的IL(仅csc Test.cs ):

.method private hidebysig static void  DeclareOutside() cil managed
{
  // Code size       79 (0x4f)
  .maxstack  2
  .locals init (bool V_0,
           int32 V_1,
           int32 V_2,
           bool V_3)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.1
  IL_0003:  br.s       IL_0045
  IL_0005:  nop
  IL_0006:  ldc.i4.0
  IL_0007:  stloc.0
  IL_0008:  ldc.i4.5
  IL_0009:  stloc.2
  IL_000a:  br.s       IL_0037
  IL_000c:  nop
  IL_000d:  ldloc.1
  IL_000e:  ldloc.2
  IL_000f:  ceq
  IL_0011:  ldc.i4.0
  IL_0012:  ceq
  IL_0014:  stloc.3
  IL_0015:  ldloc.3
  IL_0016:  brtrue.s   IL_001d
  IL_0018:  nop
  IL_0019:  ldc.i4.1
  IL_001a:  stloc.0
  IL_001b:  br.s       IL_0040
  IL_001d:  ldloc.0
  IL_001e:  ldc.i4.0
  IL_001f:  ceq
  IL_0021:  stloc.3
  IL_0022:  ldloc.3
  IL_0023:  brtrue.s   IL_0032
  IL_0025:  nop
  IL_0026:  ldstr      "Yes"
  IL_002b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0030:  nop
  IL_0031:  nop
  IL_0032:  nop
  IL_0033:  ldloc.2
  IL_0034:  ldc.i4.1
  IL_0035:  add
  IL_0036:  stloc.2
  IL_0037:  ldloc.2
  IL_0038:  ldc.i4.s   20
  IL_003a:  clt
  IL_003c:  stloc.3
  IL_003d:  ldloc.3
  IL_003e:  brtrue.s   IL_000c
  IL_0040:  nop
  IL_0041:  ldloc.1
  IL_0042:  ldc.i4.1
  IL_0043:  add
  IL_0044:  stloc.1
  IL_0045:  ldloc.1
  IL_0046:  ldc.i4.s   10
  IL_0048:  clt
  IL_004a:  stloc.3
  IL_004b:  ldloc.3
  IL_004c:  brtrue.s   IL_0005
  IL_004e:  ret
} // end of method Test::DeclareOutside

.method private hidebysig static void  DeclareInside() cil managed
{
  // Code size       79 (0x4f)
  .maxstack  2
  .locals init (int32 V_0,
           bool V_1,
           int32 V_2,
           bool V_3)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  br.s       IL_0045
  IL_0005:  nop
  IL_0006:  ldc.i4.0
  IL_0007:  stloc.1
  IL_0008:  ldc.i4.5
  IL_0009:  stloc.2
  IL_000a:  br.s       IL_0037
  IL_000c:  nop
  IL_000d:  ldloc.0
  IL_000e:  ldloc.2
  IL_000f:  ceq
  IL_0011:  ldc.i4.0
  IL_0012:  ceq
  IL_0014:  stloc.3
  IL_0015:  ldloc.3
  IL_0016:  brtrue.s   IL_001d
  IL_0018:  nop
  IL_0019:  ldc.i4.1
  IL_001a:  stloc.1
  IL_001b:  br.s       IL_0040
  IL_001d:  ldloc.1
  IL_001e:  ldc.i4.0
  IL_001f:  ceq
  IL_0021:  stloc.3
  IL_0022:  ldloc.3
  IL_0023:  brtrue.s   IL_0032
  IL_0025:  nop
  IL_0026:  ldstr      "Yes"
  IL_002b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0030:  nop
  IL_0031:  nop
  IL_0032:  nop
  IL_0033:  ldloc.2
  IL_0034:  ldc.i4.1
  IL_0035:  add
  IL_0036:  stloc.2
  IL_0037:  ldloc.2
  IL_0038:  ldc.i4.s   20
  IL_003a:  clt
  IL_003c:  stloc.3
  IL_003d:  ldloc.3
  IL_003e:  brtrue.s   IL_000c
  IL_0040:  nop
  IL_0041:  ldloc.0
  IL_0042:  ldc.i4.1
  IL_0043:  add
  IL_0044:  stloc.0
  IL_0045:  ldloc.0
  IL_0046:  ldc.i4.s   10
  IL_0048:  clt
  IL_004a:  stloc.3
  IL_004b:  ldloc.3
  IL_004c:  brtrue.s   IL_0005
  IL_004e:  ret
} // end of method Test::DeclareInside

The only differences are where the variables are located within the stack. 唯一的区别是变量在堆栈中的位置。

Inside. 内。 Variables should be scoped to their actual use. 变量应限制在其实际用途范围内。 Declaring it outside scopes the variable to the containing block which is unnecessary and could possibly cause confusion. 在变量的范围之外声明该变量到包含块是不必要的,并且可能引起混乱。

EDIT : I'm guessing that this code is just to illustrate the example, but I'd actually omit the extraneous variable and write it as: 编辑 :我猜想这段代码只是为了说明示例,但实际上我会忽略无关的变量并将其编写为:

for (int i = 0; i < MyCollection.Length; i++)
{
   foreach(MyObjectClass myObject in myObjectCollection)
   {
        if (myObject.Property == MyCollection[i].Property)
        {
             DoSomethingWith(MyCollection[i]);
             break;
        }
   }
}

我喜欢在循环中声明它们,它节省了一行代码(在同一行中声明和设置),并且更容易看出我在循环范围的内部和外部使用了哪些变量,这很好当您在做复杂的事情时。

尽可能在您使用变量的第一个位置声明变量,并让编译器担心生成最有效的IL(至少在这种情况下)。

Another point is scope. 另一点是范围。 If a variable is declared outside a loop, should I be expecting it to be used after the loop ? 如果在循环外声明了变量,我是否应该期望在循环后使用它? That is what I usually assume. 我通常就是这样假设的。

Write your code with the reader as the first thing in your mind. 与读者一起编写代码是您的第一件事。 A surprisingly small portion of code should be optimized. 令人惊讶的一小部分代码应进行优化。

There is often a tradeoff between optimization and readability. 在优化和可读性之间通常需要权衡。 Since most of the manpower is spent revising and editing existing code, it is usually the right decision to lean toward readability over optimization. 由于大部分人力都花在了修改和编辑现有代码上,因此倾向于可读性而不是优化通常是正确的决定。

The 80/20 rule is often applied here. 80/20规则经常在这里应用。

I agree siz, i depends on the scope, If the variable is not to beused anywhere except inside the loop then declare it inside the loop. 我同意siz,我取决于范围,如果除了循环内部不在其他任何地方使用变量,请在循环内部声明它。 If it is to be used after the loop has finished then it need to be declared outside. 如果要在循环完成后使用它,则需要在外部声明它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM