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

时间:2011-08-06 03:31:34

标签: c# .net garbage-collection

想象一下,我们有以下方法(伪C#):

static IEnumerable<T> Iterator<T>()
{
    switch (SomeCondition)
    {
        case CaseA:
            yield return default(T);
        case CaseB:
            yield return default(T);
            yield return default(T);
        case CaseC:
            yield return default(T);
        default:
            break;
    }
}

static IEnumerable<T> Array<T>()
{
    switch (SomeCondition)
    {
        case CaseA:
            return new[] { default(T) };
        case CaseB:
            return new[] { default(T), default(T) };
        case CaseC:
            return new[] { default(T) };
        default:
            break;
    }
}

如果我们有很多类似这种方法的调用,那么哪一个会消耗更少的内存(以及更少的GC周期)?为了实现这种Enumerable.Once()场景,编写自己的Enumerable / Enumerator是否有意义?

3 个答案:

答案 0 :(得分:1)

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

但这忽略了这一点。它更快的全部原因是因为问题空间太小而对性能不重要:一个或两个项目序列不太可能成为应用程序性能的驱动因素。在那种情况下,我会更担心其他因素,如清晰度,可维护性和创造良好习惯,而不是表现。

其中,您可能会认为数组更清晰或更清晰,因为尚未遇到迭代器的程序员仍然可以轻松理解它。就个人而言,我更喜欢yield迭代器,因为我想养成在数组之前到达迭代器的习惯,因为迭代器往往具有更好的性能特征,我想在其他人中鼓励相同的习惯。

答案 1 :(得分:1)

这个比其他人快:

static T[] Array<T>()
{
    switch (SomeCondition)
    {
        case CaseA:
            return new[1];
        case CaseB:
            return new[2];
        case CaseC:
            return new[1];
        default:
            break;
    }
}

但这真的不重要。

答案 2 :(得分:0)

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