4 ms·
I gave a concrete example in a comment on jwz's blog, referencing my blog for the 2007 @media ajax talk I gave, showing how AS3's type annotations can slow thin
by BrendanEich 16y ago
I gave a concrete example in a comment on jwz's blog, referencing my blog for the 2007 @media ajax talk I gave, showing how AS3's type annotations can slow things down. If you have a loop and annotate the loop control variable as int, but it flows into expressions that evaluate arithmetic, then per the unchanged-from-JS rules, you get IEEE754 double evaluation. This means widening not wraparound on overflow. It is non-trivial to optimize to remain in the ALU. But the int storage type means stores have to be narrowed correctly from double to int.
Not annotating the loop control variable lets two things happen: 1) everything on the FPU, which if SSE has a lot of bandwidth in parallel to the integer units, which can still handle addressing and known-int chores; 2) tracing JITs can speculate, and type inferencing JITs can infer, that the loop control fits in an int, and all evaluation and storage can use int domain.
- acqq 16y agoYes, once you have type inferencing, starting from "just a number" is more convenient and forcing everywhere, needed or not, the bigger number back to int is certainly problematic. Moreover the fastest conversion (on a typical hardware) of IEEE numbers to ints is not truncation but rounding. Excuse me for not knowing that but does JavaScript today manage not to truncate at the places (if they exist) where rounding would be acceptable?
- BrendanEich 16y agoI wish! Converting from double to int32 or uint32 in JS is far from a simple truncate or round, although it entails floor. From ECMA-262 5th Edition: 9.5 ToInt32: (Signed 32 Bit Integer) The abstract operation ToInt32 converts its argument to one of 2^32 integer values in the range −2^31 through 2^31−1, inclusive. This abstract operation functions as follows: 1. Let number be the result of calling ToNumber on the input argument. 2. If number is NaN, +0, −0, +∞, or −∞, return +0. 3. Let posInt be sign(number) * floor(abs(number)). 4. Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 2^32. 5. If int32bit is greater than or equal to 2^31, return int32bit − 2^32, otherwise return int32bit. NOTE Given the above definition of ToInt32: • The ToInt32 abstract operation is idempotent: if applied to a result that it produced, the second application leaves that value unchanged. • ToInt32(ToUint32(x)) is equal to ToInt32(x) for all values of x. (It is to preserve this latter property that +∞ and −∞ are mapped to +0.) • ToInt32 maps −0 to +0. --- end snip --- Note that this path is rare in code that does not use shift or bitwise-logical operators or certain built-in functions. See https://bugzilla.mozilla.org/show_bug.cgi?id=597814 https://bugzilla.mozilla.org/show_bug.cgi?id=597814.