我一直在谷歌搜索相当长的时间,例如'typeof'和'performance',但我无法找到满意的答案来解决以下问题。
我正在尝试使用本地运算符重载为Transcrypt Python到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);
}
});},
答案 0 :(得分:3)
这取决于JavaScript引擎。但是typeof obj
只能返回一组固定的字符串。因此,编译器/引擎可以将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实际上有一个自己的命令来测试对象是否属于某种类型,而不是字符串比较。
我不知道其他引擎是否适用,但是很可能它们做同样的事情。