标签: il

为什么C#编译器会将此变换!=比较,就像它是>比较一样?

我有机会发现C#编译器会改变这个方法:

static bool IsNotNull(object obj)
{
    return obj != null;
}
Run Code Online (Sandbox Code Playgroud)

...进入这个CIL:

.method private hidebysig static bool IsNotNull(object obj) cil managed
{
    ldarg.0   // obj
    ldnull
    cgt.un
    ret
}
Run Code Online (Sandbox Code Playgroud)

...或者,如果您更喜欢查看反编译的C#代码:

static bool IsNotNull(object obj)
{
    return obj > null;   // (note: this is not a valid C# expression)
}
Run Code Online (Sandbox Code Playgroud)

怎么把它!=翻译成" >"?

c# il cil binary-operators notnull

147
推荐指数
1
解决办法
5384
查看次数

静态方法与实例方法的性能

我的问题涉及静态方法与实例方法的性能特征及其可伸缩性.假设在这种情况下,所有类定义都在一个程序集中,并且需要多个离散指针类型.

考虑:

public sealed class InstanceClass
{
      public int DoOperation1(string input)
      {
          // Some operation.
      }

      public int DoOperation2(string input)
      {
          // Some operation.
      }

      // … more instance methods.
}

public static class StaticClass
{
      public static int DoOperation1(string input)
      {
          // Some operation.
      }

      public static int DoOperation2(string input)
      {
          // Some operation.
      }

      // … more static methods.
}
Run Code Online (Sandbox Code Playgroud)

上述类表示辅助样式模式.

在实例类中,解析实例方法需要花费一些时间来与StaticClass相反.

我的问题是:

  1. 保持状态不是问题(不需要字段或属性),使用静态类总是更好吗?

  2. 如果有相当多的静态类定义(例如100,每个都有许多静态方法),与相同数量的实例类定义相比,这会对执行性能或内存消耗产生负面影响吗?

  3. 当调用同一实例类中的另一个方法时,实例解析是否仍然发生?例如,使用[this]关键字,例如this.DoOperation2("abc")来自DoOperation1同一实例.

c# performance il static-methods

103
推荐指数
2
解决办法
5万
查看次数

为什么我的应用程序花费24%的时间进行空检查?

我有一个性能关键的二元决策树,我想把这个问题集中在一行代码上.下面是二叉树迭代器的代码,其中包含针对它运行性能分析的结果.

        public ScTreeNode GetNodeForState(int rootIndex, float[] inputs)
        {
0.2%        ScTreeNode node = RootNodes[rootIndex].TreeNode;

24.6%       while (node.BranchData != null)
            {
0.2%            BranchNodeData b = node.BranchData;
0.5%            node = b.Child2;
12.8%           if (inputs[b.SplitInputIndex] <= b.SplitValue)
0.8%                node = b.Child1;
            }

0.4%        return node;
        }
Run Code Online (Sandbox Code Playgroud)

BranchData是一个字段,而不是属性.我这样做是为了防止它被内联的风险.

BranchNodeData类如下:

public sealed class BranchNodeData
{
    /// <summary>
    /// The index of the data item in the input array on which we need to split
    /// </summary>
    internal int SplitInputIndex = 0;

    /// <summary>
    /// The …
Run Code Online (Sandbox Code Playgroud)

c# optimization performance il micro-optimization

103
推荐指数
2
解决办法
4363
查看次数

Stackoverflow在C#做拳击

我在C#中有这两个代码块:

第一

class Program
{
    static Stack<int> S = new Stack<int>();

    static int Foo(int n) {
        if (n == 0)
            return 0;
        S.Push(0);
        S.Push(1);
        ...
        S.Push(999);
        return Foo( n-1 );
    }
}
Run Code Online (Sandbox Code Playgroud)

第二

class Program
{
    static Stack S = new Stack();

    static int Foo(int n) {
        if (n == 0)
            return 0;
        S.Push(0);
        S.Push(1);
        ...
        S.Push(999);
        return Foo( n-1 );
    }
}
Run Code Online (Sandbox Code Playgroud)

他们都这样做:

  1. 创建一个堆栈(<int>第一个示例为通用,第二个示例为对象堆栈).

  2. 声明一个递归调用n次(n> = 0)的方法,并在每个步骤中在创建的堆栈内推送1000个整数.

当我运行第一个例子时Foo(30000)没有发生异常,但是第二个例子崩溃了Foo(1000),只有n = 1000.

当我看到为两种情况生成的CIL时,唯一的区别是每次推送的拳击部分: …

c# stack-overflow il

49
推荐指数
1
解决办法
2129
查看次数

C#'是'运营商在.NET 4上的发布模式优化下会受到影响吗?

下面是一个简单的测试夹具.它在Debug版本中成功,在Release版本中失败(VS2010,.NET4解决方案,x64):

[TestFixture]
public sealed class Test
{
    [Test]
    public void TestChecker()
    {
        var checker = new Checker();
        Assert.That(checker.IsDateTime(DateTime.Now), Is.True);
    }
}

public class Checker
{
    public bool IsDateTime(object o)
    {
        return o is DateTime;
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎代码优化会造成一些破坏; 如果我在Release版本上禁用它,它也可以.这让我感到很困惑.下面,我使用ILDASM来反汇编构建的两个版本:

调试IL:

.method public hidebysig instance bool IsDateTime(object o) cil managed
{
  // Code size       15 (0xf)
  .maxstack  2
  .locals init (bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.1
  IL_0002:  isinst     [mscorlib]System.DateTime
  IL_0007:  ldnull
  IL_0008:  cgt.un
  IL_000a:  stloc.0
  IL_000b:  br.s       IL_000d
  IL_000d:  ldloc.0
  IL_000e:  ret …
Run Code Online (Sandbox Code Playgroud)

c# compiler-construction optimization il

40
推荐指数
3
解决办法
964
查看次数

为什么编译器允许我在C#中将null转换为特定类型?

考虑以下代码:

var str = (string)null;
Run Code Online (Sandbox Code Playgroud)

编写代码时,这是我的IL代码:

IL_0001:  ldnull
Run Code Online (Sandbox Code Playgroud)

并且IL有任何Cast操作符但是:

var test = (string) new Object();
Run Code Online (Sandbox Code Playgroud)

IL代码是:

IL_0008:  castclass  [mscorlib]System.String
Run Code Online (Sandbox Code Playgroud)

所以Casting nullto string被忽略了.

为什么编译器允许我转换null为特定类型?

c# null il casting

37
推荐指数
4
解决办法
2687
查看次数

IL#指令未被C#公开

C#没有暴露哪些IL指令?

我指的是像sizeof和cpblk这样的指令 - 没有执行这些指令的类或命令(C#中的sizeof是在编译时计算的,而不是在运行时AFAIK计算的).

其他?

编辑:我问这个的原因(并希望这将使我的问题更有效)是因为我正在开发一个小型库,它将提供这些指令的功能.sizeof和cpblk已经实现 - 我想知道在继续之前我可能错过了什么.

编辑2:使用Eric的答案,我编写了一份说明列表:

  • 打破
  • JMP
  • 愈伤组织
  • Cpobj
  • Ckfinite
  • 前缀[1-7]
  • Prefixref
  • Endfilter
  • 未对齐
  • 尾调用
  • Cpblk
  • Initblk

列表中没有包含许多其他指令,我将它们分开,因为它们基本上是其他指令的快捷方式(压缩以节省时间和空间):

  • Ldarg [0-3]
  • Ldloc [0-3]
  • Stloc [0-3]
  • Ldc_ [I4_ [M1/S/0-8]/I8/R4/R8]
  • Ldind_ [I1/U1/I2/U2/I4/U4/I8/R4/R8]
  • Stind_ [I1/I2/I4/I8/R4/R8]
  • Conv_ [I1/I2/I4/I8/R4/R8/U4/U8/U2/U1]
  • Conv_Ovf_ [I1/I2/I4/I8/U1/U2/U4/U8]
  • Conv_Ovf_ [I1/I2/I4/I8/U1/U2/U4/U8] _Un
  • Ldelem_ [I1/I2/I4/I8/U1/U2/U4/R4/R8]
  • Stelem_ [I1/I2/I4/I8/R4/R8]

c# il instructions

33
推荐指数
2
解决办法
2659
查看次数

.NET函数被反汇编

在反汇编.NET函数时,我注意到它们都是以类似于similair的模式开始的.这个初始代码有什么作用?

此代码出现在函数应该执行的实际代码之前.它是某种参数计数验证吗?

FUNC1

private static void Foo(int i)
{
   Console.WriteLine("hello");
}

00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  push        eax 
00000004  mov         dword ptr [ebp-4],ecx 
00000007  cmp         dword ptr ds:[005C14A4h],0 
0000000e  je          00000015 
00000010  call        65E0367F 
//the console writleline code follows here and is not part of the question
Run Code Online (Sandbox Code Playgroud)

FUNC2

static private void Bar()
{
   for (int i = 0; i < 1000; i++)
   {
      Foo(i);
   }
}

00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  push        eax 
00000004  cmp         dword …
Run Code Online (Sandbox Code Playgroud)

.net c# il disassembly

31
推荐指数
1
解决办法
971
查看次数

一种易于IL代码检查的工具

有时我想快速查看我在C#中的代码片段的IL表示,以了解底层各种代码语句究竟发生了什么,就像在这里完成的那样.

我知道有ildasm,Reflector,ILSpy,dotPeek以及其他一些可用的工具.我想知道的是,如果有更优雅的方式从编写一些代码行到查看相应的IL,那么比编译.net代码,将程序集加载到其中一个程序中并找到您感兴趣的代码.

也许有一个visual studio的插件,它会为"构建和查看IL代码"或任何其他方便的方式添加一个右键单击选项?

编辑:

经过一些谷歌搜索后,我找到了NDasm codeplex项目,它完成了我想要的东西 - 集成到visual studio中.

但vcsjones的LINQPad建议也很棒,因此我将其标记为已接受,谢谢.一个非常有用的工具......

.net c# il

31
推荐指数
1
解决办法
9994
查看次数

查看从已编译表达式生成的IL代码

是否可以查看在Expression树上调用Compile()时生成的IL代码?考虑这个非常简单的例子:

class Program
{
    public int Value { get; set; }

    static void Main(string[] args)
    {
        var param = Expression.Parameter(typeof(Program));
        var con = Expression.Constant(5);
        var prop = Expression.Property(param, typeof(Program).GetProperty("Value"));
        var assign = Expression.Assign(prop, con);
        Action<Program> lambda = Expression.Lambda<Action<Program>>(assign, param).Compile();

        Program p = new Program();
        lambda(p);



        //p.Value = 5;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,表达式树执行最后一行Main所说的内容.编译应用程序,然后在Reflector中打开它.您可以看到p.Value = 5;执行分配的IL代码.但表达式树是在运行时编译和编译的.是否可以从编译中查看生成的IL代码?

c# il expression-trees .net-reflector

30
推荐指数
2
解决办法
9602
查看次数