对于逻辑值向量,当一个位向量每个条目消耗1位时,为什么R会分配4个字节?(有关示例,请参阅此问题.)
现在,我意识到R还有助于存储NA
值,但是不能用额外的位向量来完成吗?换句话说,为什么仅仅使用廉价的两位数据结构就不够了?
对于它的价值,Matlab使用1个字节作为逻辑,但它不利于NA值.我不确定为什么MathWorks不满足于一位功能,更不用说两位数据结构了,但是他们有花哨的裤子营销人员...... [我会在这个问题上为所有它值得"两点"加牛奶.;-)]
更新1.我认为所提供的架构原因是有道理的,但这感觉有点事后.我没有检查32位或16位R来查看它们的逻辑有多大 - 这可以为这个想法提供一些支持.从R Internals手册中可以看出,逻辑向量(LGLSXP)和整数(INTSXP)在每个平台上都是32位.我可以理解整数的通用大小,与字大小无关.类似地,逻辑的存储似乎也与字大小无关.但它太大了.:)
另外,如果字大小参数如此强大,看到Matlab(我认为它是一个32位的Matlab)只消耗1个字节似乎很奇怪 - 我想知道MathWorks是否选择通过权衡编程复杂性来提高内存效率以及查找子词对象的一些其他开销.
此外,肯定还有其他选择:正如Brian Diggs所说,该bit
软件包有助于位向量,这对上述问题中的问题非常有用(通过从4字节logical
值转换为任务获得8X-10X的加速速度位向量).虽然访问存储器的速度很重要,但从信息理论的角度来看,移动30-31个额外的无信息位是浪费的.例如,可以使用类似于此处描述的整数的内存技巧- 获取一堆额外的内存(V单元),然后在位级处理事物(a la bit()
).为什么不这样做并NA
为长向量保存30位(值为1,为1 )?
如果我的RAM和计算速度受到布尔值的影响,我打算转而使用bit
,但这是因为在某些情况下节省97%的空间很重要.:)
我认为这个问题的答案将来自对R的设计或内部有更深入理解的人.最好的例子是Matlab对其逻辑使用不同的大小,在这种情况下,内存字大小不是答案.Python可能与R类似,因为它的价值.
短语的一个相关方法可能是:为什么LGLSXP
在所有平台上都会有4个字节?(CHARSXP
通常是较小的,也不会那么有用吗?为什么不进行更小的,只是过度分配?)(更新使用的想法CHARSXP
可能是假的,因为操作CHARSXP
不像整数那样有用如sum
,利用相同的数据结构作为字符可能节省空间,但将限制其现有的方法可能在其上进行操作.更合适的考虑因素是使用较小的整数,如下面讨论的).
更新2已经有慕名相对于一个怎样一些很好的和启发性的答案,应该执行布尔速度和编程效率的目标的检索和处理.我认为Tommy的答案特别合理,因为它在R中出现的原因似乎来自于两个前提:
为了支持对逻辑向量的添加(注意"逻辑"由编程语言/环境定义,并且与布尔值不同),最好通过重用代码来添加整数来实现.在R的情况下,整数消耗4个字节.在Matlab的情况下,最小的整数是1个字节(即int8
).这可以解释为什么不同的东西会为逻辑写作带来麻烦.[给那些不熟悉R,它支持上逻辑值的很多数值的操作,例如sum(myVector)
,mean(myVector)
等]
遗留支持使得除了R和S-Plus已经做了很长时间以外的其他事情变得非常困难.而且,我怀疑在S,S-Plus和R的早期,如果有人做了很多布尔操作,他们在C中做了它们,而不是试图用R中的逻辑做这么多工作.
对于如何实现更好的布尔处理的目的,其他答案是很棒的 - 不要天真地假设一个人可以得到任何单个位:加载一个字最有效,然后屏蔽不感兴趣的位,如德瓦尔描述过.如果为R的布尔操作编写专门的代码(例如我在交叉表中的问题),这是非常非常有用的建议:不要迭代位,而是在单词级别工作.
感谢所有人提供了一套非常全面的答案和见解.
Der*_*all 16
在完全不知道R的情况下,我怀疑与C的原因大致相同,因为加载大小等于处理器本机字大小的速度更快.
加载单个位会很慢,尤其是来自位域,因为您必须屏蔽掉不适用于您的特定查询的位.总而言之,您只需将其加载到注册表中即可完成.由于大小差异通常不是问题,因此默认实现是使用字大小的变量.如果用户想要其他东西,则始终可以选择手动进行位移.
关于打包,至少在某些处理器上,它会导致从非对齐地址读取错误.因此,尽管你可以声明结构具有单一byte
它由两个环绕int
的byte
可能被填充为4个字节大小不分.同样,我对R没有任何了解,但我怀疑出于性能原因,行为可能是相同的.
对数组中的单个字节进行寻址是非常复杂的,比如你有一个数组bitfield
并希望在其中寻址位x
,代码将是这样的:
bit b = (bitfield[x/8] >> (x % 8)) & 1
Run Code Online (Sandbox Code Playgroud)
为您请求的位获取0或1.与从布尔数组获得值数x的直接数组寻址相比:bool a = array[x]
Tom*_*mmy 15
知道一些关于R和S-Plus的东西,我会说R最有可能与S-Plus兼容,S-Plus最有可能做到了,因为它是最简单的事情......
基本上,逻辑向量与整数向量相同,因此sum
整数的其他算法在逻辑向量上几乎不变.
在64位S-Plus中,整数是64位,因此也是逻辑向量!这是每个逻辑值8个字节 ......
@Iterator当然是正确的,逻辑矢量应该以更紧凑的形式表示.由于已经存在raw
1字节的向量类型,因此对于逻辑也使用该向量类似乎是非常简单的改变.每个值2位当然会更好 - 我可能会将它们保留为两个独立的位向量(TRUE/FALSE和NA/Valid),如果没有NA,NA位向量可能为NULL ...
无论如何,这主要是一个梦想,因为有那么多的RAPI包(使用RC/FORTRAN API的包)会破坏...
归档时间: |
|
查看次数: |
2471 次 |
最近记录: |