Для вектора логических значений, почему R выделяет 4 байта, когда битовый вектор будет потреблять 1 бит на запись? (См. этот вопрос для примеров.)
Теперь я понимаю, что R также облегчает хранение значений NA
, но разве это нельзя сделать с помощью дополнительного битового вектора? Другими словами, почему недостаточно просто использовать дешевую двухбитную структуру данных?
Для чего бы то ни было, Matlab использует 1 байт для логики, хотя это не облегчает значения NA. Я не уверен, почему MathWorks не удовлетворен однобитовой функциональностью, а тем более двухбитной структурой данных, но у них есть причудливые маркетологи ... [Я собираюсь доить два бита за все, что стоит в этом вопросе , ; -)]
Обновление 1. Я думаю, что предложенные причины архитектуры имеют некоторый смысл, но это кажется немного постфактум. Я не проверял 32-битный или 16-битный R, чтобы увидеть, насколько велики их логики - это могло бы оказать некоторую поддержку этой идее. Кажется, из руководства по внутренним ресурсам R это логично векторы (LGLSXP) и целые числа (INTSXP) - 32 бита на каждой платформе. Я могу понять универсальный размер для целых чисел, независимо от размера слова. Точно так же хранение логики также, кажется, не зависит от размера слова. Но это так БОЛЬШОЙ. :)
Кроме того, если аргумент размера слова настолько силен, мне кажется странным, что Matlab (я думаю, что это 32-битный Matlab) потребляет всего 1 байт - интересно, выбрал ли MathWorks более эффективный объем памяти с компромиссом за сложность программирования и некоторые другие затраты на поиск объектов подслов.
Кроме того, есть, конечно, и другие варианты: как отмечает Брайан Диггс, пакет bit
облегчает битовые векторы, что было очень полезно для решения проблемы в приведенном выше вопросе (ускорение задачи в 8X-10X было получено преобразование из 4 байтов logical
значений в битовые векторы). Хотя скорость доступа к памяти важна, перемещение 30-31 дополнительных неинформативных битов (с точки зрения теории информации) расточительно. Например, можно использовать что-то вроде трюков памяти, используемых для целых чисел , описанных здесь - захватить кучу дополнительной памяти (V ячеек) и затем обрабатывать вещи на уровне битов (а-ля bit()
). Почему бы не сделать это и сохранить 30 бит (1 для значения, 1 для NA
) для длинного вектора?
Поскольку булевы значения влияют на мою оперативную память и скорость вычислений, я собираюсь перейти на использование bit
, но это потому, что в некоторых случаях экономия пространства на 97% имеет значение. :)
Я думаю, что ответ на этот вопрос придет от кого-то с более глубоким пониманием дизайна R или внутренних органов. Лучшим примером является то, что Matlab использует другой размер для их логики, и размеры слов памяти не будут решением в этом случае. Python может быть похож на R, для чего это стоит.
Подобный способ выражения может быть следующим: почему LGLSXP
будет 4 байта на всех платформах? (Как правило, CHARSXP
меньше, и это не сработает? Почему бы не пойти еще меньше и просто перераспределить?) ( Обновлено Идея использования CHARSXP
, скорее всего, фальшива, потому что операции с CHARSXP
не так полезны, как операции с целыми числами, например, sum
. Использование той же структуры данных, что и у символов, может сэкономить место, но ограничит возможности использования существующих методов. Более подходящим соображением является использование меньших целых чисел, как описано ниже.)
Обновление 2. Здесь были даны несколько очень хороших и поучительных ответов, особенно относительно того, как должен реализовать поиск и обработку логических значений для целей скорости и эффективности программирования. Я думаю, что ответ Томми особенно правдоподобен в отношении , почему выглядит так в R, который, кажется, возникает из 2 предпосылок:
Для поддержки сложения на логическом векторе (обратите внимание, что «логический» определяется языком / средой программирования и не совпадает с логическим), лучше всего использовать повторное использование кода для добавления целых чисел.В случае R целые числа занимают 4 байта.В случае Matlab наименьшее целое число составляет 1 байт (т.е. int8
).Это объяснило бы, почему что-то другое было бы неприятным для логики.[Для тех, кто не знаком с R, он поддерживает множество числовых операций над логиками, таких как sum(myVector)
, mean(myVector)
и т. Д.]
Поддержка старых версий делает чрезвычайно трудным что-то делатькроме того, что было сделано в R и S-Plus в течение длительного времени.Более того, я подозреваю, что в первые дни S, S-Plus и R, если кто-то делал много логических операций, он делал их в C, а не пытался так много работать с логикой в R.
Другие ответы являются фантастическими для целей того, как можно реализовать лучшую логическую обработку - не наивно полагать, что можно получить любой отдельный бит: наиболее эффективно загрузить слово, тогдазамаскируйте биты, которые не представляют интереса, как описал Дервалл.Это очень, очень полезный совет, если нужно написать специализированный код для логических манипуляций для R (например, мой вопрос о кросс-табуляции): не перебирайте биты, а вместо этого работайте на уровне слов.
Спасибо всемдля очень тщательного набора ответов и идей.