Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(553)

Unified Diff: src/runtime.cc

Issue 7261008: Improvement to SmiLexicalCompare (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/misc-intrinsics.h ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 8424)
+++ src/runtime.cc (working copy)
@@ -45,6 +45,7 @@
#include "json-parser.h"
#include "liveedit.h"
#include "liveobjectlist-inl.h"
+#include "misc-intrinsics.h"
#include "parser.h"
#include "platform.h"
#include "runtime-profiler.h"
@@ -6647,7 +6648,7 @@
// If the integers are equal so are the string representations.
if (x_value == y_value) return Smi::FromInt(EQUAL);
- // If one of the integers are zero the normal integer order is the
+ // If one of the integers is zero the normal integer order is the
// same as the lexicographic order of the string representations.
if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
@@ -6661,36 +6662,47 @@
y_value = -y_value;
}
- // Arrays for the individual characters of the two Smis. Smis are
- // 31 bit integers and 10 decimal digits are therefore enough.
- // TODO(isolates): maybe we should simply allocate 20 bytes on the stack.
- int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms();
- int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms();
+ static const int powersOf10[] = { 1, 10, 100, 1000, 10*1000, 100*1000,
Erik Corry 2011/06/25 11:12:03 This is a constant so it should be named as a cons
sra1 2011/06/25 19:31:33 Done.
+ 1000*1000, 10*1000*1000, 100*1000*1000,
+ 1000*1000*1000 };
+ // If the integers have the same number of decimal digits they can be
+ // compared directly as the numeric order is the same as the
+ // lexicographic order. If one integer has fewer digits, it is scaled
+ // by some power of 10 to have the same number of digits as the longer
+ // integer. If the scaled integers are equal it means the shorter
+ // integer comes first in the lexicographic order.
- // Convert the integers to arrays of their decimal digits.
- int x_index = 0;
- int y_index = 0;
- while (x_value > 0) {
- x_elms[x_index++] = x_value % 10;
+ // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ int x_log2 = IntegerLog2(x_value);
+ int x_log10 = ((x_log2 + 1) * 1233) >> 12;
+ x_log10 -= x_value < powersOf10[x_log10];
+
+ int y_log2 = IntegerLog2(y_value);
+ int y_log10 = ((y_log2 + 1) * 1233) >> 12;
+ y_log10 -= y_value < powersOf10[y_log10];
+
+ int tie = EQUAL;
+
+ if (x_log10 < y_log10) {
+ // X has fewer digits. We would like to simply scale up X but that
+ // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
+ // be scaled up to 9_000_000_000. So we scale up by the next
+ // smallest power and scale down Y to drop one digit. It is OK to
+ // drop one digit from the longer integer since the final digit is
+ // past the length of the shorter integer.
+ x_value *= powersOf10[y_log10 - x_log10 - 1];
+ y_value /= 10;
+ tie = LESS;
+ } else if (y_log10 < x_log10) {
+ y_value *= powersOf10[x_log10 - y_log10 - 1];
x_value /= 10;
+ tie = GREATER;
}
- while (y_value > 0) {
- y_elms[y_index++] = y_value % 10;
- y_value /= 10;
- }
- // Loop through the arrays of decimal digits finding the first place
- // where they differ.
- while (--x_index >= 0 && --y_index >= 0) {
- int diff = x_elms[x_index] - y_elms[y_index];
- if (diff != 0) return Smi::FromInt(diff);
- }
-
- // If one array is a suffix of the other array, the longest array is
- // the representation of the largest of the Smis in the
- // lexicographic ordering.
- return Smi::FromInt(x_index - y_index);
+ if (x_value < y_value) return Smi::FromInt(LESS);
+ if (x_value > y_value) return Smi::FromInt(GREATER);
+ return Smi::FromInt(tie);
}
« src/misc-intrinsics.h ('K') | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698