Performance improvement for Math.max and Math.min
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 7 Dec 2009 08:38:20 +0000 (08:38 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 7 Dec 2009 08:38:20 +0000 (08:38 +0000)
Patch from sra.
http://codereview.chromium.org/470001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3427 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/math.js
test/mjsunit/math-min-max.js

index e3d266e..7191896 100644 (file)
@@ -29,7 +29,6 @@
 // Keep reference to original values of some global properties.  This
 // has the added benefit that the code in this file is isolated from
 // changes to these properties.
-const $Infinity = global.Infinity;
 const $floor = MathFloor;
 const $random = MathRandom;
 const $abs = MathAbs;
@@ -118,10 +117,16 @@ function MathLog(x) {
 
 // ECMA 262 - 15.8.2.11
 function MathMax(arg1, arg2) {  // length == 2
-  var r = -$Infinity;
   var length = %_ArgumentsLength();
-  for (var i = 0; i < length; i++) {
-    var n = ToNumber(%_Arguments(i));
+  if (length == 0) {
+    return -1/0;  // Compiler constant-folds this to -Infinity.
+  }
+  var r = arg1;
+  if (!IS_NUMBER(r)) r = ToNumber(r);
+  if (NUMBER_IS_NAN(r)) return r;
+  for (var i = 1; i < length; i++) {
+    var n = %_Arguments(i);
+    if (!IS_NUMBER(n)) n = ToNumber(n);
     if (NUMBER_IS_NAN(n)) return n;
     // Make sure +0 is considered greater than -0.
     if (n > r || (r === 0 && n === 0 && !%_IsSmi(r))) r = n;
@@ -131,10 +136,16 @@ function MathMax(arg1, arg2) {  // length == 2
 
 // ECMA 262 - 15.8.2.12
 function MathMin(arg1, arg2) {  // length == 2
-  var r = $Infinity;
   var length = %_ArgumentsLength();
-  for (var i = 0; i < length; i++) {
-    var n = ToNumber(%_Arguments(i));
+  if (length == 0) {
+    return 1/0;  // Compiler constant-folds this to Infinity.
+  }
+  var r = arg1;
+  if (!IS_NUMBER(r)) r = ToNumber(r);
+  if (NUMBER_IS_NAN(r)) return r;
+  for (var i = 1; i < length; i++) {
+    var n = %_Arguments(i);
+    if (!IS_NUMBER(n)) n = ToNumber(n);
     if (NUMBER_IS_NAN(n)) return n;
     // Make sure -0 is considered less than +0.
     if (n < r || (r === 0 && n === 0 && !%_IsSmi(n))) r = n;
index 0ed9912..1a98d44 100644 (file)
@@ -34,11 +34,15 @@ assertEquals(1, Math.min(2, 1));
 assertEquals(1, Math.min(1, 2, 3));
 assertEquals(1, Math.min(3, 2, 1));
 assertEquals(1, Math.min(2, 3, 1));
+assertEquals(1.1, Math.min(1.1, 2.2, 3.3));
+assertEquals(1.1, Math.min(3.3, 2.2, 1.1));
+assertEquals(1.1, Math.min(2.2, 3.3, 1.1));
 
 var o = {};
 o.valueOf = function() { return 1; };
 assertEquals(1, Math.min(2, 3, '1'));
 assertEquals(1, Math.min(3, o, 2));
+assertEquals(1, Math.min(o, 2));
 assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY / Math.min(-0, +0));
 assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY / Math.min(+0, -0));
 assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY / Math.min(+0, -0, 1));
@@ -46,7 +50,9 @@ assertEquals(-1, Math.min(+0, -0, -1));
 assertEquals(-1, Math.min(-1, +0, -0));
 assertEquals(-1, Math.min(+0, -1, -0));
 assertEquals(-1, Math.min(-0, -1, +0));
-
+assertNaN(Math.min('oxen'));
+assertNaN(Math.min('oxen', 1));
+assertNaN(Math.min(1, 'oxen'));
 
 
 // Test Math.max().
@@ -58,15 +64,22 @@ assertEquals(2, Math.max(2, 1));
 assertEquals(3, Math.max(1, 2, 3));
 assertEquals(3, Math.max(3, 2, 1));
 assertEquals(3, Math.max(2, 3, 1));
+assertEquals(3.3, Math.max(1.1, 2.2, 3.3));
+assertEquals(3.3, Math.max(3.3, 2.2, 1.1));
+assertEquals(3.3, Math.max(2.2, 3.3, 1.1));
 
 var o = {};
 o.valueOf = function() { return 3; };
 assertEquals(3, Math.max(2, '3', 1));
 assertEquals(3, Math.max(1, o, 2));
+assertEquals(3, Math.max(o, 1));
 assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY / Math.max(-0, +0));
 assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY / Math.max(+0, -0));
 assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY / Math.max(+0, -0, -1));
 assertEquals(1, Math.max(+0, -0, +1));
 assertEquals(1, Math.max(+1, +0, -0));
 assertEquals(1, Math.max(+0, +1, -0));
-assertEquals(1, Math.max(-0, +1, +0));
\ No newline at end of file
+assertEquals(1, Math.max(-0, +1, +0));
+assertNaN(Math.max('oxen'));
+assertNaN(Math.max('oxen', 1));
+assertNaN(Math.max(1, 'oxen'));