Compact optional
Наткнулся на любопытную статью про эффективные optional в Andrzej’s C++ blog.
optional
— это переменная, в которой может быть валидное значение, а может не быть. В Haskell и иже с ним такие штуки описываются монадой Maybe
, а в С++ есть реализация Boost::optional
, как и миллионы доморощенных реализаций — благо, класс несложный.
Простейшая реализация выглядит примерно так:
В классе кроме собственно значения элемента хранится bool
. Это приводит к дополнительному расходу памяти, вплоть до двукратного. Например, в реализации Boost bool
идет перед значением, которое к тому же выравнивается в памяти по своему размеру, т.е. как раз двукратное превышение.
Соответственно и по памяти это дело распухает, и в кэш хуже ложится. Другой издревле известный способ сигнализировать о том, что переменная пуста — использование магических значений типа −1. Т.е.
Такая магия идеальна по производительности, но хромает интерфейс: пользователь должен помнить, какое значение является магическим (-1, 0, MAX_INT
, …), а также может забыть сделать проверку.
Автор предлагает объединить оба эти подхода, воспользовавшись шаблонами. compact_optional
будет иметь второй шаблонный аргумент, куда принимает policy — структурку со статическими функциями, умеющую возвращать магическое значение и проверять переданное число на равенство магическому значению. Примерно так:
Тогда в самом compact_optional
хранится только значение нужного типа, а индикатором валидности служит не bool
, а наше магическое значение (в данном случае −1).
Использование — как у обычного optional
, с теми же функциями IsValid()
и GetValue()
. Недостатки — надо указывать policy и одно значение в типе жертвуется под магическое.
В реальной жизни очень часто по смыслу переменная использует не весь доступный диапазон значений (например не может быть 2 147 483 647 яблок или элементов в массиве), так что пожертвовать всегда есть что.
Думаю, эта идея — совместить плюсы четкого интерфейса и эффективность магических значений — может пригодиться не только в C++, но и в других языках програмирования, просто реализация будет немного другой.
Подробности и более полное описание плюсов и минусов — в оригинальной статье.