C# 数组或迭代器-对于返回1/2个元素的调用,哪一个具有更好的性能特征(内存方面)

C# 数组或迭代器-对于返回1/2个元素的调用,哪一个具有更好的性能特征(内存方面),c#,.net,garbage-collection,C#,.net,Garbage Collection,假设我们有以下方法(伪C#): 静态IEnumerable迭代器() { 开关(某些条件) { 案例a: 违约收益率(T); 案例B: 违约收益率(T); 违约收益率(T); 案例C: 违约收益率(T); 违约: 打破 } } 静态IEnumerable数组() { 开关(某些条件) { 案例a: 返回新的[]{default(T)}; 案例B: 返回新的[]{default(T),default(T)}; 案例C: 返回新的[]{default(T)}; 违约: 打破 } } 如果我们有许多

假设我们有以下方法(伪C#):

静态IEnumerable迭代器()
{
开关(某些条件)
{
案例a:
违约收益率(T);
案例B:
违约收益率(T);
违约收益率(T);
案例C:
违约收益率(T);
违约:
打破
}
}
静态IEnumerable数组()
{
开关(某些条件)
{
案例a:
返回新的[]{default(T)};
案例B:
返回新的[]{default(T),default(T)};
案例C:
返回新的[]{default(T)};
违约:
打破
}
}

如果我们有许多类似方法的调用,那么哪一个会消耗更少的内存(和更少的GC周期)?编写您自己的可枚举/枚举器以实现这种可枚举。Once()方案有意义吗?

数组占用更少的内存和周期,但是如果您想对返回的数据执行操作,您可能希望使用迭代器,因为迭代器实现了最好的算法,最终会加快速度。

这取决于T。例如,大型结构、字符串或字节数组使用迭代器会更好。但一般来说,对于一个或两个项目,数组可能更小

但这没有抓住重点。它之所以更快,是因为问题空间太小,以至于对性能没有太大影响:一个或两个项目序列不太可能成为应用程序性能的驱动因素。在这种情况下,我更担心的不是性能,而是清晰度、可维护性和养成良好习惯等其他因素


其中,您可以认为数组更清晰,因为还没有遇到迭代器的程序员仍然可以很容易地理解它。就我个人而言,我更喜欢使用yield迭代器,因为我想养成在数组之前使用迭代器的习惯,因为迭代器往往具有更好的性能特征,我想在其他迭代器中鼓励使用相同的习惯。

此迭代器比其他两个迭代器都快:

static T[] Array<T>()
{
    switch (SomeCondition)
    {
        case CaseA:
            return new[1];
        case CaseB:
            return new[2];
        case CaseC:
            return new[1];
        default:
            break;
    }
}
static T[]数组()
{
开关(某些条件)
{
案例a:
返回新的[1];
案例B:
返回新的[2];
案例C:
返回新的[1];
违约:
打破
}
}

但这并不重要。

在启用了适当优化的发布版本中编译并运行这两个示例时发生了什么?这两个示例都不可能成为瓶颈,请选择可读性最高的一个。这些方法是否必须具有这些签名?这肯定是一个瓶颈吗?用例是什么?这里有一些有趣的选择,但我们需要更多的信息。+1-“我会更担心其他因素,如清晰度、可维护性和养成良好习惯”完全同意!您是否有一些性能数据支持您的索赔?因为AFAICS,数组或迭代器的副本数将相等(数组一次性支付所有副本,迭代器在每个副本返回时逐段支付)。当元素的数量非常多时,数组可能会受到性能的影响,因为它使用了更多的内存,但在大多数情况下,迭代数组比迭代可枚举数组更快<代码>收益率返回有自己的一些开销,用于跟踪协同程序状态。
static T[] Array<T>()
{
    switch (SomeCondition)
    {
        case CaseA:
            return new[1];
        case CaseB:
            return new[2];
        case CaseC:
            return new[1];
        default:
            break;
    }
}