性能和内存优化(类vs结构)

时间:2018-02-14 01:30:42

标签: c# .net struct

我开始研究多边形库,其边是bezier曲线。基本没有完成工作,所以我还不能真正编写压力/性能测试程序。也没有显示太多代码。

无论如何,我都有类似的课程

public class BezierFragment
{
    Point2D[] controlPoints; // length: 2, 3 or 4
}
public struct Point2D { public double X, Y; }

但我想知道是否应该使用struct(用于更少的堆分配和更多的堆栈副本)

public struct BezierFragment
{
    byte order; // 2, 3, or 4
    Point2D p0, p1, p2, p3;
}
public struct Point2D { public double X, Y; }

后者在内存管理上要容易得多,但可能需要更多的副本(65字节)结构。我想知道哪一个是最好的。 我怎样才能找出最佳选择?

第一选择的(可能的)内存管理问题可能只有当大量Point2D []数组保存在第2代内存池中然后被销毁时才会显现......

任何提示?

1 个答案:

答案 0 :(得分:1)

<强>鉴于

class Foo : Attribute
{
   public int I { get; set; }
}

struct Foo2 
{
   public int I { get; set; }
}

private static void Method1(Foo foo)
{
   foo.I = 1;
}
private static void Method2(Foo2 foo2)
{
   foo2.I = 1;
}

<强>用法

var foo = new Foo();
//IL_0001: newobj       instance void ConsoleApp3.Foo::.ctor()
//IL_0006: stloc.0      // foo

var foo2 = new Foo2();
//IL_0007: ldloca.s     foo2
//IL_0009: initobj      ConsoleApp3.Foo2

Method1(foo);
//IL_0000: nop          
//IL_0001: ldarg.0      // foo
//IL_0002: ldc.i4.1     
//IL_0003: callvirt     instance void ConsoleApp3.Foo::set_I(int32)
//IL_0008: nop          
//IL_0009: ret   

Method2(foo2);
//IL_0000: nop          
//IL_0001: ldarga.s     foo2
//IL_0003: ldc.i4.1     
//IL_0004: call         instance void ConsoleApp3.Foo2::set_I(int32)
//IL_0009: nop          
//IL_000a: ret  

那里不是很多

但是,如果你想知道堆上的内容还有更多内容

Memory usage in .NET when creating a new class or struct

  

单个引用要么在32位进程上占用4个字节,要么占用8个字节   在64位进程上。引用是类的标准开销(如   它们是参考类型)。结构不会引起参考(嗯,   忽略任何潜在的拳击)并且是他们的内容的大小   通常。我不记得课程是否有更多的开销,不要   这么认为。

Does using “new” on a struct allocate it on the heap or stack?

正如已经指出的那样,还有更多的考虑因素

更多阅读

Coding for performance: Struct vs Class

进一步阅读

Choosing Between Class and Struct

  

CONSIDER 定义结构而不是类的实例   类型很小,通常是短暂的或通常嵌入   其他对象。

更多

  

X AVOID 定义结构,除非该类型具有以下所有内容   特性:

     
      
  • 它逻辑上表示单个值,类似于基本类型   (int,double等)。

  •   
  • 它的实例大小不超过16个字节。

  •   
  • 这是不可改变的。

  •   
  • 不必频繁装箱。

  •   
     

在所有其他情况下,您应该将类​​型定义为类。

由于您对性能感兴趣,请同时查看

Writing Faster Managed Code: Know What Things Cost