9

我已经在谷歌上搜索了很长一段时间,例如“typeof”和“performance”,但我无法找到以下问题的令人满意的答案。

我正在尝试使用本地运算符重载为Transcrypt Python to JavaScript 编译器实现复数。由于我们处理的是动态类型语言,因此无法预测变量中的数据类型。

如果我翻译x + y成 JavaScript,打开运算符重载,它将翻译为例如__add__ (x, y)为了做正确的事情,该__add__函数必须检查两者x以及y它们是否是“普通”JavaScript 数字,或者它们中的一个或两个属于“复杂”类型,因为这需要特殊操作。

最明显的方法是测试typeof x == 'number'. 但是,来自 C/C++ 背景,使用具有六个字符的字符串测试相等性似乎非常低效,首先必须从内存中检索,只能添加两个整数,对于许多处理器来说,一次解析,将只有一条指令。

最让我惊讶的是,像这样的检查在互联网上随处可见,这是正常的做法。有谁知道是否x == 'number'或可能x === 'number'以某种方式巧妙地优化以防止完整的字符串比较。

为了进一步澄清问题,这是我当前的__add__操作员代码,使用字符串比较。

def __add__ (self, other):
    if __typeof__ (other) == 'number':   # Translates to: if (typeof other == 'number') {
        return complex (self.real + other, self.imag)
    else:   # Other is complex
        return complex (self.real + other.real, self.imag + other.imag)

如果没有,任何人都可以提示我更快地区分数字和任意非数字对象。

感谢您的提示。现在的来源是:

def __sub__ (self, other):
    if __typeof__ (other, 'number'):
        return complex (self.real - other, self.imag)
    else:
        return complex (self.real - other.real, self.imag - other.imag)

被某某人翻译:

elif node.func.id == '__typeof__':
    self.emit ('typeof ')
    self.visit (node.args [0])
    self.emit (' === ') # Give JavaScript string interning a chance to avoid char by char comparison
    self.visit (node.args [1])
    return

到:

get __add__ () {return __get__ (this, function (self, other) {
    if (typeof other === 'number') {
        return complex (self.real + other, self.imag);
    }
    else {
        return complex (self.real + other.real, self.imag + other.imag);
    }
});},
4

1 回答 1

9

这取决于 JavaScript 引擎。但是 atypeof obj只能返回一组固定的字符串。因此,编译器/引擎可以将 a 优化typeof obj === 'number'为不进行字符串比较的测试,但使用更有效的测试。

创建的字节码 V8if( typeof obj === 'number' )将是这样的:

268 S> 0x24110cfe4b0 @   62 : 13 04     LdaImmutableCurrentContextSlot [4]
       0x24110cfe4b2 @   64 : 65 00     TestTypeOf #0
       0x24110cfe4b4 @   66 : 86 16     JumpIfFalse [22] (0x24110cfe4ca @ 88)

所以至少 v8 实际上有一个自己的命令来测试一个对象是否属于某种类型,这不是字符串比较。

我不知道这是否适用于其他引擎,但它们很可能会做同样的事情。

于 2018-07-13T16:01:50.200 回答