Optimize JSON stringify for arrays.

Review URL: http://codereview.chromium.org/6164004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6286 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sandholm@chromium.org 2011-01-12 14:16:19 +00:00
parent e2f8c938c3
commit 5be396cb30

View File

@ -179,26 +179,62 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
function BasicSerializeArray(value, stack, builder) {
var len = value.length;
if (len == 0) {
builder.push("[]");
return;
}
if (!%PushIfAbsent(stack, value)) {
throw MakeTypeError('circular_structure', []);
}
builder.push("[");
var len = value.length;
for (var i = 0; i < len; i++) {
var before = builder.length;
BasicJSONSerialize(i, value, stack, builder);
if (before == builder.length) builder.push("null");
var val = value[0];
if (IS_STRING(val)) {
// First entry is a string. Remaining entries are likely to be strings too.
builder.push(%QuoteJSONString(val));
for (var i = 1; i < len; i++) {
builder.push(",");
val = value[i];
if (IS_STRING(val)) {
builder.push(%QuoteJSONString(val));
} else {
var before = builder.length;
BasicJSONSerialize(i, value[i], stack, builder);
if (before == builder.length) builder.push("null");
}
}
} else if (IS_NUMBER(val)) {
// First entry is a number. Remaining entries are likely to be numbers too.
builder.push(NUMBER_IS_FINITE(val) ? %_NumberToString(val) : "null");
for (var i = 1; i < len; i++) {
builder.push(",");
val = value[i];
if (IS_NUMBER(val)) {
builder.push(NUMBER_IS_FINITE(val)
? %_NumberToString(val)
: "null");
} else {
var before = builder.length;
BasicJSONSerialize(i, value[i], stack, builder);
if (before == builder.length) builder.push("null");
}
}
} else {
var before = builder.length;
BasicJSONSerialize(0, val, stack, builder);
if (before == builder.length) builder.push("null");
for (var i = 1; i < len; i++) {
builder.push(",");
before = builder.length;
val = value[i];
BasicJSONSerialize(i, val, stack, builder);
if (before == builder.length) builder.push("null");
}
}
stack.pop();
if (builder.pop() != ",") {
builder.push("[]"); // Zero length array. Push "[" back on.
} else {
builder.push("]");
}
}
function BasicSerializeObject(value, stack, builder) {
if (!%PushIfAbsent(stack, value)) {
@ -210,7 +246,7 @@ function BasicSerializeObject(value, stack, builder) {
builder.push(%QuoteJSONString(p));
builder.push(":");
var before = builder.length;
BasicJSONSerialize(p, value, stack, builder);
BasicJSONSerialize(p, value[p], stack, builder);
if (before == builder.length) {
builder.pop();
builder.pop();
@ -228,8 +264,7 @@ function BasicSerializeObject(value, stack, builder) {
}
function BasicJSONSerialize(key, holder, stack, builder) {
var value = holder[key];
function BasicJSONSerialize(key, value, stack, builder) {
if (IS_SPEC_OBJECT(value)) {
var toJSON = value.toJSON;
if (IS_FUNCTION(toJSON)) {
@ -266,7 +301,7 @@ function BasicJSONSerialize(key, holder, stack, builder) {
function JSONStringify(value, replacer, space) {
if (%_ArgumentsLength() == 1) {
var builder = [];
BasicJSONSerialize('', {'': value}, [], builder);
BasicJSONSerialize('', value, [], builder);
if (builder.length == 0) return;
var result = %_FastAsciiArrayJoin(builder, "");
if (!IS_UNDEFINED(result)) return result;