方法性能返回的C#结构

方法性能返回的C#结构,c#,performance,memory-management,struct,C#,Performance,Memory Management,Struct,假设我有一个这样的结构: public struct MyCustomDataset : IEnumerable<float> { public float v1; public float v2; public float v3; public MyCustomDataset(float v1, float v2, float v3) { this.v1 = v1; this.v2 = v2; thi

假设我有一个这样的结构:

public struct MyCustomDataset : IEnumerable<float> {
    public float v1;
    public float v2;
    public float v3;

    public MyCustomDataset(float v1, float v2, float v3) {
        this.v1 = v1;
        this.v2 = v2;
        this.v3 = v3;
    }

    // Enumerable impl
    public IEnumerator<float> GetEnumerator() {
        yield return v1;
        yield return v2;
        yield return v3;
    }
    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
}
我想知道它是否比MyCustomDataset是class而不是struct更优化。我需要知道,因为我在应用程序主循环中调用test(),所以MyCustomDataset将在每个应用程序迭代中分配。因此,我不会让MyCustomDataset成为一个类,因为这就像性能自杀。我使用struct进行协同排序,因为我怀疑它在这种情况下的行为或多或少类似于基元类型

性能可以吗

我不会将MyCustomDataset分配给任何类字段,我只会在方法体中读取它,可能会将它传递到几个方法调用中,因此它将出现在几个局部范围中。

您:

因为这就像是自杀

你为什么这么认为?您所指的结构和类之间有什么区别


我认为,如果你觉得struct或多或少像“原始类型”(你的话),那么你应该使用它。这只有三个
float
值(可能总共96位),因此对于值类型来说足够小。但是如果你坚持使用一个结构,那么让字段
只读

简单回答:如果你已经知道瓶颈可能在哪里,为什么不自己测量时间呢?旁注:你的结构是一种很多人会称之为可变的结构。考虑制定三个字段<代码> Read Ont/Cuth>(因此<代码>公共只读浮标V1;< /COD>等)。如果您需要更改
MyCustomDataset
实例中的单个坐标(例如
v1
),那么也许您应该将其设置为类,因为可变结构可能会让人困惑。是的,我忘记了,但这也是我所想的。泰铢通知;]@JeppeStigNielsen:一个暴露的字段结构基本上是一堆用胶带粘在一起的变量。如果结构的目的只是将一些变量与风管胶带绑定在一起,以便它们可以作为一个组传递,那么公开的字段结构将是一个完美的选择。微软的指导方针假定结构应该像类一样工作,但要从结构中获得最佳性能,需要以不同的方式使用它们。像
Point
这样的东西应该具有与
Decimal
完全不同的语义;前者应该是一个公开的字段结构,而后者不是。@supercat我知道这是你的观点,我相信人们可以用这种方式编写优秀的代码,但很多人的观点不同,那就是:永远不要“公开”结构的字段,也就是说,永远不要允许字段在构造函数完成后更改值。询问者当然可以自己决定。创建可变结构并不违法,但很多人都反对。好吧,每秒几十个对象对性能不好,因为GC必须经常运行清理,垃圾收集对处理器来说相当麻烦,不是吗?@Fisher你可以每秒在堆上创建数百万个小对象,垃圾收集器不会有任何问题。但是你自己试试看。我的建议是根据“对象”的语义在
struct
class
之间进行选择,以及您希望它是通过值还是通过引用进行复制和传递。如果以后性能会出现问题,首先测量并分析瓶颈在哪里。这可能不是你的
MyCustomDataset
values/objects。是的,昨天我和我的朋友(那是一个比我好得多的编码员:P)谈过这件事,他也说了同样的话=我不必要地对性能如此担忧。
public static MyCustomDataset test() {
    return new MyCustomDataset(1,2,3);
}

public static void test2() {
    MyCustomDataset ds = test();
    /* doing stuff with ds */
}