性能 if (typeof x == 'number')?

Performance if (typeof x == 'number')?

我在谷歌上搜索了很长时间,例如'typeof' 和 'performance',但我一直未能找到以下问题的满意答案。

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

如果我将 x + y 翻译成 JavaScript,打开运算符重载,它将翻译例如作为 __add__ (x, y) 为了做正确的事情,__add__ 函数必须检查 xy 是否是 'ordinary' JavaScript数字或者其中一个或两个都是 'complex' 类型,因为这需要特殊操作。

最明显的方法是测试 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);
    }
});},

这取决于 JavaScript 引擎。但是一个typeof obj只能return一组固定的字符串。所以一个compiler/engine可以将一个typeof obj === 'number'优化成一个不做字符串比较的测试,而是使用一个更高效的测试。

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

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

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

我不知道其他引擎是否也是如此,但它们很可能做同样的事情。