OCaml 和内存中的自定义类型
Custom Types in OCaml and Memory
运行
type expression =
| Num of int
| Var of string
| Let of string * expression * expression
| Binop of string * expression * expression;;
在一个 utop 会话中大约需要 8 秒。
现在,如果我们跳到 单独的 utop 会话和 运行
type expression =
| Num of int
| Var of string
| Let of string * expression * expression * expression * expression
| Binop of string * expression * expression;;
这大约需要 13 秒。
最后,让我们在同一节课中完成这两项工作
type expression =
| Num of int
| Var of string
| Let of string * expression * expression
| Binop of string * expression * expression;;
type expression_1 =
| Num of int
| Var of string
| Let of string * expression_1 * expression_1 * expression_1 * expression_1
| Binop of string * expression_1 * expression_1;;
第一种和单独的会话一样需要8秒,但是以前的13秒操作现在是3秒!这是怎么回事?
我对 OCaml 在类型方面所做的所有工作知之甚少;也许它能够通过一些智能缓存从 2 表达式树构建 4 表达式树?
还是更复杂的东西?
例如,由于我的自定义类型在这两种情况下都有递归组件,它是否检查 expression_1
和 expression
是否具有某种 "structural" 相似性?随着编译器在程序中注释和统一类型,当它遇到新类型时它可能有几个选项(没有双关语意):它是否明确使用 预定义 类型注释为推断手头类型的线索,还是它会遍历它知道的类型,然后遍历我定义的自定义类型?
编译器是否首先评估某种类型,然后提出一种表示来检查它是否是某种类型?在这个例子中,是不是把所有expression * expression
...的递归结构构造成一棵树?
我真的不知道,但我想知道!
在您的实验中,您测量的不是 OCaml,而是 utop,OCaml 的交互式解释器。虽然您显示的数字确实离谱且不寻常,但它们与 OCaml 性能无关。它们表明您的系统出现严重错误。
说到 OCaml,它的特点是性能极佳的编译器,每毫秒能够输入数千个表达式,因此您几乎察觉不到它。事实上,OCaml 经常被用作各种高级语言和定理证明器的目标语言,如 Coq、Ott 和 F*,因此它被用来编译机器生成的代码,通常有很多。
回到你的例子,我怀疑你要么 运行在一个有很多文件的文件夹中 utop,要么你的 .ocamlinit 文件 运行 计算速度很慢,或者您没有向我们完整描述您的实验。或者你在 utop 中遇到了一些错误。
我还可以建议使用 down
一个新的 OCaml 顶级库。例如,(第一个符号是提示符)
$ ocaml
# #use "topfind";;
# #require "down";;
或者只是 运行 ocaml
使用 rlwrap
,例如,
$ rlwrap ocaml
或者,甚至,在您的 browser1.
中尝试 OCaml
此外,由于您想了解 OCaml 对您的类型定义做了什么——没有什么复杂的只是解析它并执行一些健全性检查。即使在 30 年前,也不会花费超过一秒钟的时间。
1))在这种情况下,OCaml 编译器本身被编译为 Javascript 并且被您的浏览器编译为 运行,它仍然会接受您的定义在几毫秒内完成。
运行
type expression =
| Num of int
| Var of string
| Let of string * expression * expression
| Binop of string * expression * expression;;
在一个 utop 会话中大约需要 8 秒。
现在,如果我们跳到 单独的 utop 会话和 运行
type expression =
| Num of int
| Var of string
| Let of string * expression * expression * expression * expression
| Binop of string * expression * expression;;
这大约需要 13 秒。
最后,让我们在同一节课中完成这两项工作
type expression =
| Num of int
| Var of string
| Let of string * expression * expression
| Binop of string * expression * expression;;
type expression_1 =
| Num of int
| Var of string
| Let of string * expression_1 * expression_1 * expression_1 * expression_1
| Binop of string * expression_1 * expression_1;;
第一种和单独的会话一样需要8秒,但是以前的13秒操作现在是3秒!这是怎么回事?
我对 OCaml 在类型方面所做的所有工作知之甚少;也许它能够通过一些智能缓存从 2 表达式树构建 4 表达式树?
还是更复杂的东西?
例如,由于我的自定义类型在这两种情况下都有递归组件,它是否检查 expression_1
和 expression
是否具有某种 "structural" 相似性?随着编译器在程序中注释和统一类型,当它遇到新类型时它可能有几个选项(没有双关语意):它是否明确使用 预定义 类型注释为推断手头类型的线索,还是它会遍历它知道的类型,然后遍历我定义的自定义类型?
编译器是否首先评估某种类型,然后提出一种表示来检查它是否是某种类型?在这个例子中,是不是把所有expression * expression
...的递归结构构造成一棵树?
我真的不知道,但我想知道!
在您的实验中,您测量的不是 OCaml,而是 utop,OCaml 的交互式解释器。虽然您显示的数字确实离谱且不寻常,但它们与 OCaml 性能无关。它们表明您的系统出现严重错误。
说到 OCaml,它的特点是性能极佳的编译器,每毫秒能够输入数千个表达式,因此您几乎察觉不到它。事实上,OCaml 经常被用作各种高级语言和定理证明器的目标语言,如 Coq、Ott 和 F*,因此它被用来编译机器生成的代码,通常有很多。
回到你的例子,我怀疑你要么 运行在一个有很多文件的文件夹中 utop,要么你的 .ocamlinit 文件 运行 计算速度很慢,或者您没有向我们完整描述您的实验。或者你在 utop 中遇到了一些错误。
我还可以建议使用 down
一个新的 OCaml 顶级库。例如,(第一个符号是提示符)
$ ocaml
# #use "topfind";;
# #require "down";;
或者只是 运行 ocaml
使用 rlwrap
,例如,
$ rlwrap ocaml
或者,甚至,在您的 browser1.
中尝试 OCaml此外,由于您想了解 OCaml 对您的类型定义做了什么——没有什么复杂的只是解析它并执行一些健全性检查。即使在 30 年前,也不会花费超过一秒钟的时间。
1))在这种情况下,OCaml 编译器本身被编译为 Javascript 并且被您的浏览器编译为 运行,它仍然会接受您的定义在几毫秒内完成。