我遇到了很多优化提示,说明你应该将你的课程标记为密封以获得额外的性能优势.
我运行了一些测试以检查性能差异,但没有找到.难道我做错了什么?我错过了密封课程会给出更好结果的情况吗?
有没有人进行测试并看到了差异?
帮我学习:)
我很想知道为什么会这样.请阅读下面的代码示例以及每个部分下面的注释中发出的相应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()
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器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;
}
Run Code Online (Sandbox Code Playgroud)
为什么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()
Run Code Online (Sandbox Code Playgroud)
和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()
Run Code Online (Sandbox Code Playgroud)
我只能猜到它,因为在M2我们知道它p不是空的,它就像它
new MyClass().MyMethod();
Run Code Online (Sandbox Code Playgroud)
这是真的吗?
如果是,如果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
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
条形图定义如下
public class Bar …Run Code Online (Sandbox Code Playgroud) 我运行了以下控制台应用程序:
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 < …Run Code Online (Sandbox Code Playgroud) 空传播是一个非常好的功能 - 但实际魔法在哪里以及如何发生?哪里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();
}
}
Run Code Online (Sandbox Code Playgroud)
编译器发出以下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 …Run Code Online (Sandbox Code Playgroud) 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