我遇到了很多优化提示,说明你应该将你的课程标记为密封以获得额外的性能优势.
我运行了一些测试以检查性能差异,但没有找到.难道我做错了什么?我错过了密封课程会给出更好结果的情况吗?
有没有人进行测试并看到了差异?
帮我学习:)
我很想知道为什么会这样.请阅读下面的代码示例以及每个部分下面的注释中发出的相应IL:
using System;
class Program
{
    static void Main()
    {
        Object o = new Object();
        o.GetType();
        // L_0001: newobj instance void [mscorlib]System.Object::.ctor()
        // L_0006: stloc.0 
        // L_0007: ldloc.0 
        // L_0008: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
        new Object().GetType();
        // L_000e: newobj instance void [mscorlib]System.Object::.ctor()
        // L_0013: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
    }
}
为什么编译器callvirt为第一部分发出a 而call第二部分发出a ?是否有任何理由编译器会发出callvirt非虚方法的指令?如果在某些情况下编译器将callvirt为非虚拟方法发出一个,这会产生类型安全问题吗?
最近有件事引起了我的好奇心。
当他们做同样的事情时,为什么该Enumerable.Any(Func<TSource, bool> predicate)方法比手动 foreach慢得多?
我一直在搞乱一些基准并想到了这一点。我正在检查List<int>大约位于列表一半的内容和项目。
以下是我对几种不同大小的列表的测试结果:
项目:1 000,搜索项目:543
| 方法 | 意思是 | 比率 | 已分配 | 分配比例 | 
|---|---|---|---|---|
| 福里奇 | 838.3纳秒 | 1.00 | - | 不适用 | 
| 任何 | 3,348.8 纳秒 | 4.05 | 40乙 | 不适用 | 
项目:10 000,搜索项目:5 432
| 方法 | 意思是 | 比率 | 已分配 | 分配比例 | 
|---|---|---|---|---|
| 福里奇 | 7.988 我们 | 1.00 | - | 不适用 | 
| 任何 | 30.991 我们 | 3.88 | 40乙 | 不适用 | 
项目:100 000,搜索项目:54 321
| 方法 | 意思是 | 比率 | 已分配 | 分配比例 | 
|---|---|---|---|---|
| 福里奇 | 82.35 我们 | 1.00 | - | 不适用 | 
| 任何 | 328.86 我们 | 4.00 | 40乙 | 不适用 | 
有两个基准:
foreach带有if语句的手册我很好奇是否有一种方法this可以在C#中的虚方法中为null.我认为这是不可能的.我在现有代码中看到,在代码审查期间,我希望100%肯定对其删除进行评论,但我想要一些确认和社区的更多上下文.this != null在任何非静态/实例方法中都是这种情况吗?否则它会是一个空指针异常对吗?我正在考虑扩展方法以及我可能不熟悉多年Java的C#特性.
鉴于这两种方法:
    static void M1(Person p)
    {
        if (p != null)
        {
            var p1 = p.Name;
        }
    }
    static void M2(Person p)
    {
        var p1 = p?.Name;
    }
为什么M1 IL代码使用callvirt:
IL_0007:  brfalse.s  IL_0012
IL_0009:  nop
IL_000a:  ldarg.0
IL_000b:  callvirt   instance string ConsoleApplication4.Person::get_Name()
和M2 IL使用call:
brtrue.s   IL_0007
IL_0004:  ldnull
IL_0005:  br.s       IL_000d
IL_0007:  ldarg.0
IL_0008:  call       instance string ConsoleApplication4.Person::get_Name()
我只能猜到它,因为在M2我们知道它p不是空的,它就像它
new MyClass().MyMethod();
这是真的吗?
如果是,如果p在其他线程中将为null?
我的问题的前提,用简单的英语:
Foo取决于名为的库BarFooBar依赖于Foo请考虑以下示例:
class Program
{
    static void Main(string[] args)
    {
        Foo foo = Foo.Instance;
        int id = foo.Id; // Compiler is happy
        foo.DoWorkOnBar(); // Compiler is not happy
    }
}
Foo定义如下
public class Foo : Bar
{
    public new static Foo Instance { get => (Foo)Bar.Instance; }
    public new int Id { get => Bar.Id; }
    public void DoWorkOnBar()
    {
        Instance.DoWork();
    }
}
条形图定义如下
public class Bar …我运行了以下控制台应用程序:
class Program
{
    static void Main(string[] args)
    {
        int n = 10000;
        Stopwatch s = new Stopwatch();
        s.Start();
        List<int> numbers = GetListNumber(n);
        foreach (var number in numbers)
        {
        }
        s.Stop();
        Console.WriteLine(s.Elapsed);
        Console.WriteLine();
        s.Restart();
        foreach (var number in GetEnumerator(n))
        {
        }
        s.Stop();
        Console.WriteLine(s.Elapsed);
        Console.ReadKey();
    }
    static List<int> GetListNumber(int n)
    {
        List<int> numbers = new List<int>();
        for (int i = 0; i < n; i++)
            numbers.Add(i);
        return numbers;
    }
    static IEnumerable<int> GetEnumerator(int n)
    {
        for (int i = 0; i < …空传播是一个非常好的功能 - 但实际魔法在哪里以及如何发生?哪里frm?.Close()得到改变if(frm != null) frm.Close();-它是否真正得到改变那种代码呢?
对于以下代码段:
struct Test
{
    public override string ToString()
    {
        return "";
    }
}
public class Program
{
    public static void Main()
    {
        Test a = new Test();
        a.ToString();
        Int32 b = 5;
        b.ToString();
    }
}
编译器发出以下IL:
  .locals init ([0] valuetype ConsoleApplication2.Test a,
           [1] int32 b)
  IL_0000:  nop
  IL_0001:  ldloca.s   a
  IL_0003:  initobj    ConsoleApplication2.Test
  IL_0009:  ldloca.s   a
  IL_000b:  constrained. ConsoleApplication2.Test
  IL_0011:  callvirt   instance string [mscorlib]System.Object::ToString()
  IL_0016:  pop
  IL_0017:  ldc.i4.5
  IL_0018:  stloc.1
  IL_0019:  ldloca.s   b
  IL_001b:  call       instance string [mscorlib]System.Int32::ToString()
  IL_0020:  pop …c# ×8
il ×3
.net ×2
clr ×2
.net-6.0 ×1
boxing ×1
c#-4.0 ×1
c#-6.0 ×1
cil ×1
dependencies ×1
frameworks ×1
linq ×1
null ×1
optimization ×1
performance ×1
propagation ×1
roslyn ×1
this ×1
type-safety ×1