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