Массивы или итераторы - которые имеют лучшие характеристики производительности (с точки зрения памяти) для вызовов, которые возвращают один / два элемента - PullRequest
5 голосов
/ 06 августа 2011

Представьте, что у нас есть следующие методы (псевдо 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 / Enumerator для реализации такого рода сценария Enumerable.Once ()?

Ответы [ 3 ]

1 голос
/ 08 августа 2011

Это зависит от T. Например, большая структура, строки или байтовые массивы будут лучше работать с итератором. Но в целом для одного или двух элементов массив, вероятно, меньше.

Но это не относится к делу. Вся причина в том, что он быстрее, в том, что проблемное пространство настолько мало, что не имеет существенного значения для производительности: одна или две последовательности элементов вряд ли будут определяющим фактором для производительности вашего приложения. В этом сценарии, а не производительность, я бы больше беспокоился о других факторах, таких как ясность, ремонтопригодность и формирование хороших привычек.

Из них можно утверждать, что массив яснее или чище, потому что программисты, которые еще не сталкивались с итераторами, все еще могут легко его понять. Лично я предпочитаю итератор yield, потому что я хочу иметь привычку обращаться к итераторам перед массивами, потому что итераторы, как правило, имеют лучшие характеристики производительности, и я хочу поощрять такую ​​же привычку в других.

1 голос
/ 08 августа 2011

Этот быстрее, чем другие:

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

Но на самом деле это не имеет большого значения.

0 голосов
/ 08 августа 2011

Массивы занимают меньше памяти и циклов, но если вы хотите воздействовать на возвращенные данные, вам следует использовать итераторы, поскольку итераторы реализуют лучший из алгоритмов, которые в конечном итоге ускорят процесс.

...