【发布时间】:2015-04-30 00:58:19
【问题描述】:
我正在用 JavaScript 模拟一个 8 位微处理器。我已将每个操作码函数名称存储在一个数组中,并调用与从我的虚拟内存读取的操作码相关的 256 个函数中的每一个,如下所示:
this.OP[opcode] = 'this.LDAA()';
eval(this.OP[opcode]);
我最近更改了我的代码以摆脱 eval(),如下所示:
this.OP[opcode] = 'LDAA';
this[this.OP[opcode]]();
在 Mac Safari 中,以上两者之间没有明显的速度差异,这让我感到惊讶。我认为后者会更快,但我的虚拟时钟速度对于两者来说大致相同(目前峰值为 4MHz)。
由于与使用 eval() 相比,使用索引方法调用似乎没有速度损失,我希望也更新我的虚拟内存系统,但我对要使用的语法有一个心理障碍。
写一个字节我有:
RAM = {
write : [],
setup : function() {
this.write[addr] = "this.simpleWrite(addr,byte)";
},
writeByte : function(addr,byte) {
eval(this.write[addr]);
},
simpleWrite : function(addr,byte) {
this.memory[addr] = byte;
},
};
RAM.writeByte( someAddress, someValue );
我正在使用这种索引的间接方法,因此我可以将设备映射到地址范围并根据需要放置断点和观察点,所有这些都拦截内存读取和写入 - 最大限度地提高性能。
关于如何在保持数据吞吐量的同时丢失 eval 的任何建议?
我想将外部方法映射到间接数组中,并且能够传递参数(要写入的值)。因此,无论哪个虚拟硬件使用公共接口访问虚拟内存,其他虚拟硬件都可以拦截该进程并在必要时监视或更改值。
【问题讨论】:
-
如果您正好有 256 个操作码,那么使用操作码索引数组以获取函数的 256 个函数引用(不是函数名)的数组应该是最快的。在某些 JS 引擎中,解释器可以很好地优化仅被视为纯数组的数组,这比对象键查找要好得多。与所有与性能相关的问题一样,您必须在相关浏览器中进行测试才能确定。使用
eval()不可能是最快的。 -
你的
setup中addr的值是多少??? -
addr 是 write[] 数组的任何有效索引(实际上是 0 到 65535)。我将查找函数名称和引用之间的区别,如果我的意思正确,那是个好主意,谢谢。
-
@jfriend00 - 我没有 256 个函数,因为有些是重复的,NOP 等,但我可以轻松地将其扩展为 256,然后有一个由索引调用的匿名函数数组 - 我喜欢这样的声音,谢谢。
标签: javascript performance indexed indirection jump-table