C# 关于类实例的性能更改

C# 关于类实例的性能更改,c#,C#,Student.cs class Student { public int getAge() { return 10; } } class Program { public static void Main(string[] args) { Student s = new Student(); int a = s.getAge(); int b = new Student().getAge(); } } Pr

Student.cs

class Student
{
   public int getAge()
   {
      return 10;
   }
}
class Program
{
   public static void Main(string[] args)
   {
      Student s = new Student();
      int a = s.getAge();
      int b = new Student().getAge();
   }
}
Program.cs

class Student
{
   public int getAge()
   {
      return 10;
   }
}
class Program
{
   public static void Main(string[] args)
   {
      Student s = new Student();
      int a = s.getAge();
      int b = new Student().getAge();
   }
}
当以上述方式访问类时,会有任何性能差异吗

当以上述方式访问类时,会有任何性能或安全性差异吗

没有

查找性能差异的一种方法是观察编译给定代码时生成的IL语句。当您在调试模式下编译程序时,这两种老化方式之间确实存在细微差异:

.locals init (
    [0] class Student,
    [1] int32,
    [2] int32
)

IL_0000: nop
IL_0001: newobj instance void Student::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance int32 Student::getAge()
IL_000d: stloc.1
IL_000e: newobj instance void Student::.ctor()
IL_0013: call instance int32 Student::getAge()
IL_0018: stloc.2
IL_0019: ret
请注意,
IL_000d
之前的语句用于变量
s
a
的赋值。语句
IL_000e
IL_0013
用于分配变量
b
。请注意,在后者中没有用于分配局部变量的中间语句

但是,当您使用发行版配置编译代码时,差异完全消失,因为编译器可以轻松确定变量
s
a
b
不会在任何后续语句中使用

IL_0000: newobj instance void Student::.ctor()
IL_0005: callvirt instance int32 Student::getAge()
IL_000a: pop
IL_000b: newobj instance void Student::.ctor()
IL_0010: call instance int32 Student::getAge()
IL_0015: pop
IL_0016: ret

即使您指示以后将使用变量
a
b
,IL代码对于这两种情况仍然相同

例如,如果源代码修改如下:

Student s = new Student();
int a = s.getAge();
int b = new Student().getAge();
Console.WriteLine(a);
Console.WriteLine(b);
IL现在改为

IL_0000: newobj instance void Student::.ctor()
IL_0005: callvirt instance int32 Student::getAge()
IL_000a: stloc.0
IL_000b: newobj instance void Student::.ctor()
IL_0010: call instance int32 Student::getAge()
IL_0015: ldloc.0
IL_0016: call void [System.Console]System.Console::WriteLine(int32)
IL_001b: call void [System.Console]System.Console::WriteLine(int32)
IL_0020: ret

所以我想说,这两种情况之间不应该有任何性能差异


关于安全性,我观察到的唯一区别是第二种情况中没有存储实例对象。但这也不会有任何区别。

在这两种情况下,您都创建了一个
Student
实例,并调用
getAge()
。为什么你期望这里会有一些不同?你在考虑什么样的“安全性”差异?为什么你会担心在如此小的情况下的性能?过早优化。将其推迟到您必须编写关键代码和更多经验的时候。