比var x = new Stuff(); x.DoStuff();
快new Stuff().DoStuff();
?
我不确定为什么,但我在我的代码中注意到第一种方法使它更快,谁知道哪一种更快,为什么?
答案 0 :(得分:9)
实际上第二个应该更快,因为它执行的操作更少。我们以此程序为例:
class Program
{
public void Foo() { }
static void Main()
{}
static void Method1()
{
var x = new Program();
x.Foo();
}
static void Method2()
{
new Program().Foo();
}
}
以下是在Release模式下编译时Method1和Method2的外观:
.method private hidebysig static void Method1() cil managed
{
.maxstack 1
.locals init (
[0] class Program x)
L_0000: newobj instance void Program::.ctor()
L_0005: stloc.0
L_0006: ldloc.0
L_0007: callvirt instance void Program::Foo()
L_000c: ret
}
.method private hidebysig static void Method2() cil managed
{
.maxstack 8
L_0000: newobj instance void Program::.ctor()
L_0005: call instance void Program::Foo()
L_000a: ret
}
当然不应该问这种微优化问题。
答案 1 :(得分:7)
在这种情况下,您可以将 DoStuff 设为静态方法。
然后使用
Stuff.DoStuff();
看看
答案 2 :(得分:4)
这是他们产生的IL代码:
new Stuff().DoStuff();
:
// Code size 11 (0xb)
.maxstack 8
IL_0000: newobj instance void ConsoleApplication1.Stuff::.ctor()
IL_0005: call instance void ConsoleApplication1.Stuff::DoStuff()
IL_000a: ret
var x = new Stuff(); x.DoStuff();
:
// Code size 13 (0xd)
.maxstack 1
.locals init ([0] class ConsoleApplication1.Stuff x)
IL_0000: newobj instance void ConsoleApplication1.Stuff::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt instance void ConsoleApplication1.Stuff::DoStuff()
IL_000c: ret
当迭代两次变化1000000次时,new Stuff().DoStuff();
版本使用的时间减少约20%。我没什么可担心的(一百万次迭代的差异是0.8毫秒)。
答案 3 :(得分:3)
IMO两个版本的速度应完全相同。也许你的基准是有缺陷的?
答案 4 :(得分:1)
第一个版本需要在本地版本中存储对x的引用,后者版本不需要,如果不使用其他指令,则无法完成。但是,即使是最轻微的代码更改也会改变性能。
请不要高估JIT的效率,JIT需要平衡编译速度和生成代码的效率,JIT'er不是用于生成机器代码的笔最终应用程序CIL代码。