我已经看过这个理论并理解为什么第一个比第二个更快的解释,但我想在tcl中看到字节码。在python shell中,很容易看到字节码,但我找不到在tclsh中查看它的解决方案。
#first approach
expr {3 * 4}
#second approach
expr 3 * 4
任何帮助都将不胜感激。
答案 0 :(得分:2)
要查看Tcl生成的字节码,请使用tcl::unsupported::disassemble
(假设您已获得Tcl 8.5或更高版本)。这是你的例子:
% tcl::unsupported::disassemble script {expr {3 * 4}}
ByteCode 0x0x103058910, refCt 1, epoch 95, interp 0x0x100829a10 (epoch 95)
Source "expr {3 * 4}"
Cmds 1, src 12, inst 3, litObjs 1, aux 0, stkDepth 1, code/src 0.00
Commands 1:
1: pc 0-1, src 0-11
Command 1: "expr {3 * 4}"
(0) push1 0 # "12"
(2) done
% tcl::unsupported::disassemble script {expr 3 * 4}
ByteCode 0x0x1030b2f10, refCt 1, epoch 95, interp 0x0x100829a10 (epoch 95)
Source "expr 3 * 4"
Cmds 1, src 10, inst 14, litObjs 4, aux 0, stkDepth 5, code/src 0.00
Commands 1:
1: pc 0-12, src 0-9
Command 1: "expr 3 * 4"
(0) push1 0 # "3"
(2) push1 1 # " "
(4) push1 2 # "*"
(6) push1 1 # " "
(8) push1 3 # "4"
(10) concat1 5
(12) exprStk
(13) done
正如您所看到的,在一种情况下,Tcl发现它有一个编译时常量并使用它,而在另一种情况下,它正在构建一个表达式并将其触发到运行时表达式引擎中(通过{{1}我可以告诉你递归地调用编译器,在这种情况下是什么 一个全新的对象,因此最终不会缓存任何东西而且会很昂贵。)
您可以反汇编其他内容,特别是exprStk
(针对程序),proc
(适用于lambda
条款)和apply
(适用于TclOO方法;此处需要Tcl 8.6)。
在Tcl 8.4及更早版本中,可以让反汇编程序打印出来。您只需将全局method
变量设置为tcl_traceCompile
- 如果使用正确的配置选项构建Tcl库,2
是最有用的变量 - 然后强制编译代码;反汇编(相同的格式)直接打印到真正的控制台。但这是一种糟糕的方式; 8.5在所有版本中添加了命令版本,以便远离那些可怕的全局变量。 (还有--enable-symbols=all
...)
8.6.3也将有另一个反汇编程序,它产生适合进一步编写脚本的输出。