- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
还没有在其他任何地方看到过这个“功能”。我知道第 32 位用于垃圾收集。但是为什么它只适用于整数而不适用于其他基本类型呢?
最佳答案
这被称为标记指针表示,并且是几十年来在许多不同的解释器、VM 和运行时系统中使用的一种非常常见的优化技巧。几乎每个 Lisp 实现都使用它们,许多 Smalltalk VM,许多 Ruby 解释器,等等。
通常,在这些语言中,您总是传递指向对象的指针。一个对象本身由一个对象头组成,其中包含对象元数据(如对象的类型、它的类、可能访问控制限制或安全注释等),然后是实际的对象数据本身。因此,一个简单的整数将被表示为一个指针加上一个由元数据和实际整数组成的对象。即使使用非常紧凑的表示,对于一个简单的整数来说,这也类似于 6 字节。
此外,您不能将这样的整数对象传递给 CPU 来执行快速整数运算。如果要添加两个整数,实际上只有两个指针,它们指向要添加的两个整数对象的对象头的开头。因此,您首先需要对第一个指针执行整数运算,以将偏移量添加到存储整数数据的对象中。然后您必须取消引用该地址。对第二个整数再次执行相同操作。现在您有两个整数,您实际上可以要求 CPU 相加。当然,您现在需要构造一个新的整数对象来保存结果。
所以,为了执行一个整数加法,你实际上需要执行三个整数加法加两个指针解引用加一个对象构造。而你几乎占用了 20 字节。
然而,诀窍在于,对于所谓的不可变值类型(如整数),您通常不需要对象头中的所有元数据:您可以将所有这些内容都保留下来,然后简单地合成它(这是 VM-nerd-说“假货”),当有人愿意看的时候。整数将始终具有类 Integer
,无需单独存储该信息。如果有人使用反射来计算整数的类别,您只需回复 Integer
没有人会知道您实际上并没有将这些信息存储在对象头中,事实上,甚至没有对象头(或对象)。
因此,诀窍是将对象的值存储在指向对象的指针中,有效地将两者合二为一。
有些 CPU 在指针(所谓的标记位)内实际上有额外的空间,允许您在指针本身内存储有关指针的额外信息。额外的信息,如“这实际上不是一个指针,这是一个整数”。示例包括 Burroughs B5000、各种 Lisp 机器或 AS/400。不幸的是,目前大多数主流 CPU 都没有该功能。
然而,有一个出路:本地址在字边界上不对齐时,大多数当前的主流 CPU 的工作速度会明显变慢。有些甚至根本不支持非对齐访问。
这意味着实际上,所有指针都可以被 4 整除,这意味着它们总是以两个 0
结尾。位。这使我们能够区分真正的指针(以 00
结尾)和实际上是伪装整数的指针(以 1
结尾的指针)。它仍然给我们留下了所有以 10
结尾的指针。可以自由地做其他事情。此外,大多数现代操作系统为自己保留了非常低的地址,这给了我们另一个可以处理的区域(例如,以 24 0
s 开头并以 00
结尾的指针)。
因此,您可以将 31 位整数编码为指针,只需将其向左移动 1 位并添加 1
。到它。你可以用它们执行非常快速的整数运算,只需适本地移动它们(有时甚至不需要)。
我们如何处理那些其他地址空间?嗯,典型的例子包括编码 float
s 在其他大地址空间和许多特殊对象,如 true
, false
, nil
、127个ASCII字符、一些常用的短字符串、空列表、空对象、空数组等0
附近地址。
例如,在 MRI、YARV 和 Rubinius Ruby 解释器中,整数按照我上面描述的方式进行编码,false
被编码为地址 0
(恰好也是 C 中 false
的表示),true
作为地址 2
(恰好是 true
移位一位的 C 表示)和 nil
如 4
.
关于integer - 为什么 OCaml 中的 int 只有 31 位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3773985/
我正在尝试以更命令的方式表达一组链式调用。例如,图像我们有一个函数,它接受一个列表和一个元素,并将该元素附加到列表的末尾: let insert l e = l @ [e] 我想一次插入几个元素。
是否有一个完整的列表(或详尽的规则)可以给 OCaml 中的自定义中缀运算符提供可能的名称? 最佳答案 如 OCaml manual 中所述, 中缀运算符必须匹配正则表达式 [-=<>@^|&+*/$
我想开始使用 OCaml 编程。由于我是 Windows 用户,我知道最好使用 Netbeans 的 OCaml 插件。 我已经从以下链接下载了上述插件:http://ocamlplugin.loki
能够做到这一点以获得最大速度不是很重要吗? 编辑: 例如,Clojure 有 map ,它使用多个核心。 Harrop 博士写道(2011 年 1 月 9 日): 语言中添加的新功能,例如一流 OCa
我在 x86 机器上用字节码编译 OCaml 程序,然后将字节码传输到 ppc64 机器。假设 ppc64 机器有 ocamlrun(为 ppc64 编译),我能在 ppc64 架构上执行我的程序吗?
我创建了一个新模块,它只是名称很长的模块的较短别名: module M = ModuleWithLongName 我处于最终可执行文件的大小很重要的情况。上面的构造是由编译器合理处理的吗(即 M 实际
我在使用 ocaml 时遇到了麻烦。 我想创建一个函数,每次调用它时都会增加我的计数器,并将我的 vargen 字符串与计数器编号连接起来,然后返回这个新字符串。 我没有成功的做法是: let (co
我正在学习 OCaml,我对变量的不变性有点困惑。根据我正在阅读的书,变量是不可变的。到目前为止一切顺利,但为什么我可以这样做: let foo = 42 let foo = 4242 我错过了什么?
非尾递归组合函数可以这样写: let rec combinations l k = if k List.length l then [] else if k = 1 then List.ma
我有一段包含camlp4引用的代码。 let f_name = "my_func" > 运行此程序后 camlp4of ,它产生这个: Ast.StExp (_loc, (Ast.ExAp
如何在 OCaml 中模拟这个 Python 习语? if __name__=="__main__": main() 见 RosettaCode其他编程语言中的示例。 最佳答案 Ocaml 中没
我开始学习 Ocaml,使用 hickey book ,我被困在练习 3.4,第 9 部分 让 x x = x + 1 在 x 2 运算结果为3 ,但我不明白为什么? 最佳答案 当你写 let x x
Rust具有线性系统。有什么(好的)方法可以在 OCaml 中模拟这个吗?例如,当使用 ocaml-lua 时,我想确保仅当 Lua 处于特定状态(堆栈顶部的表等)时才调用某些函数。 编辑 :这是最近
在 OCaml?我知道非常酷的Bitstring图书馆,但是 虽然这将是在某些协议(protocol)中解析二进制数据的好方法, 它不支持异或或移位等按位运算。 我相信该库使用的底层数据结构是 只是
我们可以像这样构造一个无限列表: let rec endless = 1::endless 我认为它会吃掉所有的内存,但是当我在 utop 中尝试时,好像不是这样。 utop显示列表已构建: val
是否可以通过合并列表的元素而不是创建列表的列表来创建列表? 例子: List.combine ["A";"B"] ["C";"D"];; 我得到: [("A", "C"); ("B", "D")] 有
我想在 OCaml 中创建一个查找表。该表将有 7000 多个条目,在查找时(通过 int)返回一个字符串。用于此任务的适当数据结构是什么?表是否应该从基本代码中外部化,如果是这样,如何“包括”查找表
我正在评估 Ocaml 顶层中的一段非常简单的代码: let p5 () = print_int 5;; p5 ();; print_string "*************************
记录和元组之间是否有任何区别而不仅仅是句法差异? 有性能差异吗? 元组和记录的实现是否相同? 您是否有可以使用元组完成但不能使用记录完成的事情的示例(和 反之)? 最佳答案 模数语法它们几乎相同。主要
OCaml 中的 ` 运算符有什么作用? let int_of_meth = function | `GET -> 0 | `POST -> 1 | `PUT ->
我是一名优秀的程序员,十分优秀!