Conversation
Said macros alias the built-in isFinite() and isNaN() functions for now but will someday be replaced by optimized inline versions.
@@ -98,7 +98,7 @@ function Buffer(subject, encoding) { | |||
|
|||
|
|||
function SlowBuffer(length) { | |||
length = ~~length; | |||
length = TO_INT32(length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm. oversight on my part. we don't allow negative lengths, so might as well use TO_UINT32(length)
.
Just me, but |
@bnoordhuis overall I'm diggin' the changes. this'll take some fielding on the PR's, but overall should allow for a lot better consistency across the board. plus I like the ease of search. |
@bnoordhuis Here's my diff for diff --git a/src/macros.py b/src/macros.py
index ad54a00..3c06702 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -5,6 +5,8 @@ macro IS_NUMBER(arg) = (typeof(arg) === 'number');
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_SYMBOL(arg) = (typeof(arg) === 'symbol');
macro IS_UNDEFINED(arg) = (typeof(arg) === 'undefined');
+macro IS_NAN(arg) = !((arg) >= (arg));
+macro IS_FINITE(arg) = ((arg) < 1/0 && (arg) > -1/0);
# These macros follow the semantics of V8's %_Is*() functions.
macro IS_ARRAY(arg) = (Array.isArray(arg));
@@ -15,10 +17,6 @@ macro IS_REGEXP(arg) = ((arg) instanceof RegExp);
macro IS_BUFFER(arg) = ((arg) instanceof Buffer);
-# TODO(bnoordhuis) Replace with optimized versions someday.
-macro NUMBER_IS_FINITE(arg) = isFinite(arg);
-macro NUMBER_IS_NAN(arg) = isNaN(arg);
-
macro TO_BOOLEAN(arg) = (!!(arg));
macro TO_INT32(arg) = ((arg) >> 0);
macro TO_NUMBER(arg) = (+(arg));
|
Should To test if something actually is NaN, you can do |
|
So, what's the motivation for doing this with macros rather than just using JavaScript? |
On Jul 24, 2013 5:28 PM, "Isaac Z. Schlueter" notifications@github.com
Whatevs. That's just an old habit from a bug that used to exist in IE, but |
One issue I see is that your versions evaluate their argument twice, e.g.
Consistency, better grep factor, easier to change (you only have to update the macro.) |
I guess one reason for doing it like that is that it's immune to EDIT: V8 also generates slightly better code in the 1/0 case, it saves an IC lookup. |
Yes, if that's something we decide to worry about, we should also replace all our
Fair enough.
That can be avoided by wrapping in an IIFE. macro NUMBER_IS_NAN(arg) = ((function(x) { return x !== x; })(+arg))
macro NUMBER_IS_FINITE(arg) = ((function(x) { return x < 1/0 && x > -1/0; })(+arg)) |
Yeah, but that creates tiny closures all over the place. V8 won't usually (maybe never) inline them. |
V8 would inline them if we defined these as JavaScript functions rather than macros. Since Also! We have
But, if we cast to a number and THEN test it for NaN-ness, then it's the same as just calling isNaN |
NUMBER_IS_NAN is the Number.isNaN implementation, not the global isNaN. @bnoordhuis the check I have is very cheap in the case the developer is |
I generated IRHydra output for the following: function test0(arg) { return (!(arg >= arg)) ? 0 : 1; }
function test1(arg) { return isNaN(arg) ? 0 : 1; }
function runTest() {
var a0 = 0, a1 = 0;
for (var i = 0; i < 1e6; i++) {
a0 += test0(i);
a1 += test1(i);
}
}
runTest(); Here are he
Now, the output for
Finally if I change the input to the following: function runTest() {
var a0 = 0;
var a1 = 0;
for (var i = 0; i < 1e6; i++) {
a0 += test0(i % 1e4 === 0 ? 'abc' : i);
a1 += test1(i % 1e4 === 0 ? 'abc' : i);
}
} We get the following:
|
Per @isaacs request, I tested
|
FWIW, I can confirm Trevor's observations: the |
We've decided to go in a separate direction for the time being. We may explore this path at a later date. |
/cc @trevnorris - work-in-progress, just gauging if you feel it's going in the right direction.