Какое-либо значительное повышение производительности при помощи побитовых операторов вместо простого интервала суммирует в C#?

Я начал работать с C# несколько недель назад, и я нахожусь теперь в ситуации, где я должен создать флаг "набора битов" для обработки различных случаев в алгоритме. У меня есть таким образом две опции:

    enum RelativePositioning
    {
        LEFT = 0,
        RIGHT = 1,
        BOTTOM  = 2,
        TOP = 3,
        FRONT = 4,
        BACK = 5
    }

    pos = ((eye.X < minCorner.X ? 1 : 0) << (int) RelativePositioning.LEFT)
        + ((eye.X > maxCorner.X ? 1 : 0) << (int) RelativePositioning.RIGHT)
        + ((eye.Y < minCorner.Y ? 1 : 0) << (int) RelativePositioning.BOTTOM)
        + ((eye.Y > maxCorner.Y ? 1 : 0) << (int) RelativePositioning.TOP)
        + ((eye.Z < minCorner.Z ? 1 : 0) << (int) RelativePositioning.FRONT)
        + ((eye.Z > maxCorner.Z ? 1 : 0) << (int) RelativePositioning.BACK);

Или:

    enum RelativePositioning
    {
        LEFT = 1,
        RIGHT = 2,
        BOTTOM  = 4,
        TOP = 8,
        FRONT = 16,
        BACK = 32
    }

    if (eye.X < minCorner.X) { pos += (int) RelativePositioning.LEFT;   }
    if (eye.X > maxCorner.X) { pos += (int) RelativePositioning.RIGHT;  }
    if (eye.Y < minCorner.Y) { pos += (int) RelativePositioning.BOTTOM; }
    if (eye.Y > maxCorner.Y) { pos += (int) RelativePositioning.TOP;    }
    if (eye.Z > maxCorner.Z) { pos += (int) RelativePositioning.FRONT;  }
    if (eye.Z < minCorner.Z) { pos += (int) RelativePositioning.BACK;   }

Я, возможно, использовал что-то как ((eye.X > maxCorner.X) << 1) но C# не позволяет неявный кастинг от bool до интервала, и тернарный оператор был достаточно подобен. Мой вопрос теперь: есть ли какое-либо повышение производительности в использовании первой версии по второму?

Спасибо
Tommaso

7
задан tunnuz 18 May 2010 в 12:50
поделиться

3 ответа

Оператор inline if (?, :) сгенерирует почти такой же IL, как и стандартный список if во втором примере. Единственное различие, которое вы увидите здесь, это конкретные операции, которые будет выполнять процессор, и я могу поспорить, что ADD будет быстрее, чем SHL.
Поскольку вы все равно будете складывать результаты, я бы выбрал второй пример (к тому же он гораздо легче читается).

EDIT
Я только что проверил IL обоих примеров, и это противоречит тому, что я сказал выше.
Первый пример генерирует гораздо меньше IL (на 34 строки меньше), поэтому вам придется провести тест производительности, чтобы определить, быстрее ли он.

5
ответ дан 6 December 2019 в 19:34
поделиться

Значительно быстрее? нет. Чуть быстрее? Немного.

0
ответ дан 6 December 2019 в 19:34
поделиться

Вы обязательно должны использовать атрибут Flags для своего перечисления. Таким образом, это будет выглядеть примерно так:

[Flags]
public enum RelativePositionings
{
    None = 0,
    Left = 1,
    Right = 2,
    Bottom  = 4,
    Top = 8,
    Front = 16,
    Back = 32
}

С его помощью вы можете делать такие вещи, как:

var position = RelativePositionings.Left | RelativePositionings.Front;

и проверять каждое состояние:

if(position.HasFlag(RelativePositioning.Left))
{
    //To do: if left bit is set?
}
8
ответ дан 6 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: