I've been Googling quite some time for e.g. 'typeof' and 'performance', but I haven't been able to find a satisfactory answer to the following problem.
I am trying to implement complex numbers for the Transcrypt Python to JavaScript compiler, using local operator overloading. Since we're dealing with a dynamically typed language, it cannot be predicted what type of data will be in a variable.
If I translate x + y
to JavaScript, having operator overloading switched on, it will translate e.g. as __add__ (x, y)
In order to do the right thing, the __add__
function has to check for both x
and y
whether they are 'ordinary' JavaScript numbers or if one of them or both of them are of type 'complex', since that requires special operations.
The most obvious way to do that is to test for typeof x == 'number'
. However, coming from a C/C++ background, it seems ridiculously inefficient to test for equality with a string with six characters which on top of that first has to be retrieved from memory, only to possible add two integers, which for many processors, once parsed, would be only one instruction.
What amazes me most is that checks like this are advised everywhere around the internet as the normal thing to do. Does anyone know if x == 'number'
or possible x === 'number'
is somehow cleverly optimized to prevent a full string comparison.
To further clarify the problem, here's my current code for the __add__
operator, using the string comparison.
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)
If not can anyone hint me on a quicker way to distinguish between a number and an arbitrary non-numerical object.
Thanks for the tips. The source is now:
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)
translated by:
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
to:
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);
}
});},
The typeof operator returns a string that contains the primitive type of the given variable. When using this operator with numbers, it can return a few possibilities. If you are using it with the number primitive, it will return 'number' . If you use it with an instance of the Number class, it will return 'object' .
The TypeOf function is an important tool when dealing with complex code. It allows a programmer to quickly check a variable's data type—or whether it's “undefined” or “null”—without going through the code line by line! Additionally, the TypeOf function can also check whether an operand is an object or not.
typeof is a JavaScript keyword that will return the type of a variable when you call it. You can use this to validate function parameters or check if variables are defined. There are other uses as well. The typeof operator is useful because it is an easy way to check the type of a variable in your code.
That depends on the JavaScript engine. But a typeof obj
can only return a fixed set of strings. So a compiler/engine can optimize a typeof obj === 'number'
into a test that does not do a string comparison, but uses a more efficient test.
The byte code V8 created for if( typeof obj === 'number' )
will be something like this:
268 S> 0x24110cfe4b0 @ 62 : 13 04 LdaImmutableCurrentContextSlot [4]
0x24110cfe4b2 @ 64 : 65 00 TestTypeOf #0
0x24110cfe4b4 @ 66 : 86 16 JumpIfFalse [22] (0x24110cfe4ca @ 88)
So at least v8 does in fact have an own command to test if an object is of a certain type, which is not a string comparison.
I don't know if this is true for the other engines, but it is likely that they do the same thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With