Why does the C # compiler create a new Action instance for each delegate passed in?

Consider the following code:

public static void M() {
    A(V);
    A(V);
    A(V);
}

public static void V() {

}

public static void A(Action x) {
    x();   
}

This compiles off-screen as:

public static void M() {
    A(new Action(V));
    A(new Action(V));
    A(new Action(V));
}

However, we can write our own simple performance boost that reduces unnecessary garbage:

private static readonly Action v = new Action(V);
A(v);
A(v);
A(v);

In this very simple case, is there any reason Roslin could not have done such an optimization?

If the answer is no, what should I do if the methods are not static but are members of the instance? What about captured private variables?

+4
source share
2 answers

we can write our own simple performance improvement that reduces unnecessary garbage

- , , , .

, , "" . , , . gen 2. ? , , .

- , ?

, , .

, , , , , . .

, , , . # . . , , , , , , , "".

, # lambdas. , lambdas :

void M() { Action x = () => {}; ... }

, :

static Action anon = null;
void M() 
{
  if (anon == null) anon = () => {};
  Action x = anon;
  ...

, , , ?

, , .

, , , . , .

, , # .

?

? , , , , .

# , lambdas, , .

, , . , , .

, , # .

, . " ?" ", ". " # ​​ ​​ ?" .

- , , 2009 .

Roslyn . , Roslyn , . ; , , . . CSE.

+17

, .

-, . ,

public static void M() { A(V); }

public static void M() { A(new Action(V)); }

. , , IL :

IL_000C:  ldnull  
IL_000D:  ldftn       UserQuery.V
IL_0013:  newobj      System.Action..ctor
IL_0018:  call        UserQuery.A
IL_0014:  ldarg.0     
IL_0015:  ldarg.0     
IL_0016:  ldftn       UserQuery.V
IL_001C:  newobj      System.Action..ctor
IL_0021:  call        UserQuery.A
IL_0027:  ldarg.0     
IL_0028:  ldarg.0     
IL_0029:  ldftn       UserQuery.V
IL_002F:  newobj      System.Action..ctor
IL_0034:  call        UserQuery.A

V IL_000D. , , IL_000C: ldarg.0, . IL_0013: newobj, ( ) , > . , , A.

:

IL_0001:  ldsfld      UserQuery.v
IL_0006:  call        UserQuery.A
IL_000B:  nop         
IL_000C:  ldsfld      UserQuery.v
IL_0011:  call        UserQuery.A
IL_0016:  nop         
IL_0017:  ldsfld      UserQuery.v
IL_001C:  call        UserQuery.A

v ldsfld. , - , A.

, , , , , , Roslyn ... IL, . , , , .

+1

Source: https://habr.com/ru/post/1673667/


All Articles