性能 if (typeof x == 'number')?
Performance if (typeof x == 'number')?
我在谷歌上搜索了很长时间,例如'typeof' 和 'performance',但我一直未能找到以下问题的满意答案。
我正在尝试使用局部运算符重载为 Transcrypt Python 到 JavaScript 编译器实现复数。由于我们处理的是动态类型语言,因此无法预测变量中的数据类型。
如果我将 x + y
翻译成 JavaScript,打开运算符重载,它将翻译例如作为 __add__ (x, y)
为了做正确的事情,__add__
函数必须检查 x
和 y
是否是 '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 实际上有一个自己的命令来测试对象是否属于某种类型,这不是字符串比较。
我不知道其他引擎是否也是如此,但它们很可能做同样的事情。
我在谷歌上搜索了很长时间,例如'typeof' 和 'performance',但我一直未能找到以下问题的满意答案。
我正在尝试使用局部运算符重载为 Transcrypt Python 到 JavaScript 编译器实现复数。由于我们处理的是动态类型语言,因此无法预测变量中的数据类型。
如果我将 x + y
翻译成 JavaScript,打开运算符重载,它将翻译例如作为 __add__ (x, y)
为了做正确的事情,__add__
函数必须检查 x
和 y
是否是 '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 实际上有一个自己的命令来测试对象是否属于某种类型,这不是字符串比较。
我不知道其他引擎是否也是如此,但它们很可能做同样的事情。