admin管理员组文章数量:1303551
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 plex numbers for the Transcrypt Python to JavaScript piler, 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 'plex', since that requires special operations.
The most obvious way to do that is to test for typeof x == 'number'
. However, ing 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 parison.
To further clarify the problem, here's my current code for the __add__
operator, using the string parison.
def __add__ (self, other):
if __typeof__ (other) == 'number': # Translates to: if (typeof other == 'number') {
return plex (self.real + other, self.imag)
else: # Other is plex
return plex (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 plex (self.real - other, self.imag)
else:
return plex (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 parison
self.visit (node.args [1])
return
to:
get __add__ () {return __get__ (this, function (self, other) {
if (typeof other === 'number') {
return plex (self.real + other, self.imag);
}
else {
return plex (self.real + other.real, self.imag + other.imag);
}
});},
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 plex numbers for the Transcrypt Python to JavaScript piler, 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 'plex', since that requires special operations.
The most obvious way to do that is to test for typeof x == 'number'
. However, ing 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 parison.
To further clarify the problem, here's my current code for the __add__
operator, using the string parison.
def __add__ (self, other):
if __typeof__ (other) == 'number': # Translates to: if (typeof other == 'number') {
return plex (self.real + other, self.imag)
else: # Other is plex
return plex (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 plex (self.real - other, self.imag)
else:
return plex (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 parison
self.visit (node.args [1])
return
to:
get __add__ () {return __get__ (this, function (self, other) {
if (typeof other === 'number') {
return plex (self.real + other, self.imag);
}
else {
return plex (self.real + other.real, self.imag + other.imag);
}
});},
Share
Improve this question
edited Jul 13, 2018 at 15:36
taras
6,91510 gold badges45 silver badges53 bronze badges
asked Aug 11, 2016 at 16:54
Jacques de HoogeJacques de Hooge
7,0002 gold badges32 silver badges47 bronze badges
13
- 2 It's the thing to do in Javascript because there is quite literally no other way to do it. In any case, JS is quite definitely not concerned about optimisations at this level; if you are, you probably should use something else. – Daniel Roseman Commented Aug 11, 2016 at 17:02
- I think you have to use isinstance. It is more pythonic way – luminousmen Commented Aug 11, 2016 at 17:02
- 1 @Daniel Roseman: I know JS isn't ideal for this kind of stuff, still it's what we're stuck with in the browser. But admitted, it'll never be C++. – Jacques de Hooge Commented Aug 11, 2016 at 17:05
- 1 asm.js might be a better target but also you should actually measure the performance impact of these checks for your workload first. JS runtimes do all sorts of (multi-stage) optimization so musing about how many instructions something is when your source and target are two high-level languages is not going to get your anything – pvg Commented Aug 11, 2016 at 17:13
-
2
Reading the spec, I would expect
===
to be faster for your use case. Everything else will be speculation about the internals of the various engines. Empirical testing will tell you where you stand. Of course things could change at the will of the vendors. ecma-international/ecma-262/7.0/… – Ben Aston Commented Aug 11, 2016 at 17:27
1 Answer
Reset to default 12That depends on the JavaScript engine. But a typeof obj
can only return a fixed set of strings. So a piler/engine can optimize a typeof obj === 'number'
into a test that does not do a string parison, 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 mand to test if an object is of a certain type, which is not a string parison.
I don't know if this is true for the other engines, but it is likely that they do the same thing.
本文标签: javascriptPerformance if (typeof x39number39)Stack Overflow
版权声明:本文标题:javascript - Performance if (typeof x == 'number')? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741680874a2392160.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论