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

Side by Side Diff: src/array.js

Issue 6902144: Handle join of sparse arrays with non-empty separator more efficiently. (Closed)
Patch Set: Add test for empty separator. Fix brainfart. Created 9 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 keys.push(key); 60 keys.push(key);
61 } 61 }
62 } 62 }
63 } 63 }
64 } 64 }
65 keys.sort(function(a, b) { return a - b; }); 65 keys.sort(function(a, b) { return a - b; });
66 return keys; 66 return keys;
67 } 67 }
68 68
69 69
70 function SparseJoinWithSeparator(array, len, convert, separator) {
71 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
72 var totalLength = 0;
73 var elements = new InternalArray(keys.length * 2);
74 var previousKey = -1;
75 for (var i = 0; i < keys.length; i++) {
76 var key = keys[i];
77 if (key != previousKey) { // keys may contain duplicates.
78 var e = array[key];
79 if (!IS_STRING(e)) e = convert(e);
80 elements[i * 2] = key;
81 elements[i * 2 + 1] = e;
82 previousKey = key;
83 }
84 }
85 return %SparseJoinWithSeparator(elements, len, separator);
86 }
87
88
70 // Optimized for sparse arrays if separator is ''. 89 // Optimized for sparse arrays if separator is ''.
71 function SparseJoin(array, len, convert) { 90 function SparseJoin(array, len, convert) {
72 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len)); 91 var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, len));
73 var last_key = -1; 92 var last_key = -1;
74 var keys_length = keys.length; 93 var keys_length = keys.length;
75 94
76 var elements = new InternalArray(keys_length); 95 var elements = new InternalArray(keys_length);
77 var elements_length = 0; 96 var elements_length = 0;
78 97
79 for (var i = 0; i < keys_length; i++) { 98 for (var i = 0; i < keys_length; i++) {
(...skipping 23 matching lines...) Expand all
103 var is_array = IS_ARRAY(array); 122 var is_array = IS_ARRAY(array);
104 123
105 if (is_array) { 124 if (is_array) {
106 // If the array is cyclic, return the empty string for already 125 // If the array is cyclic, return the empty string for already
107 // visited arrays. 126 // visited arrays.
108 if (!%PushIfAbsent(visited_arrays, array)) return ''; 127 if (!%PushIfAbsent(visited_arrays, array)) return '';
109 } 128 }
110 129
111 // Attempt to convert the elements. 130 // Attempt to convert the elements.
112 try { 131 try {
113 if (UseSparseVariant(array, length, is_array) && (separator.length == 0)) { 132 if (UseSparseVariant(array, length, is_array)) {
114 return SparseJoin(array, length, convert); 133 if (separator.length == 0) {
134 return SparseJoin(array, length, convert);
135 } else {
136 return SparseJoinWithSeparator(array, length, convert, separator);
137 }
115 } 138 }
116 139
117 // Fast case for one-element arrays. 140 // Fast case for one-element arrays.
118 if (length == 1) { 141 if (length == 1) {
119 var e = array[0]; 142 var e = array[0];
120 if (IS_STRING(e)) return e; 143 if (IS_STRING(e)) return e;
121 return convert(e); 144 return convert(e);
122 } 145 }
123 146
124 // Construct an array for the elements. 147 // Construct an array for the elements.
125 var elements = new InternalArray(length); 148 var elements = new InternalArray(length);
126 149
127 // We pull the empty separator check outside the loop for speed! 150 // We pull the empty separator check outside the loop for speed!
128 if (separator.length == 0) { 151 if (separator.length == 0) {
129 var elements_length = 0; 152 var elements_length = 0;
130 for (var i = 0; i < length; i++) { 153 for (var i = 0; i < length; i++) {
131 var e = array[i]; 154 var e = array[i];
132 if (!IS_UNDEFINED(e)) { 155 if (!IS_STRING(e)) e = convert(e);
133 if (!IS_STRING(e)) e = convert(e); 156 elements[elements_length++] = e;
134 elements[elements_length++] = e;
135 }
136 } 157 }
137 elements.length = elements_length; 158 elements.length = elements_length;
138 var result = %_FastAsciiArrayJoin(elements, ''); 159 var result = %_FastAsciiArrayJoin(elements, '');
139 if (!IS_UNDEFINED(result)) return result; 160 if (!IS_UNDEFINED(result)) return result;
140 return %StringBuilderConcat(elements, elements_length, ''); 161 return %StringBuilderConcat(elements, elements_length, '');
141 } 162 }
142 // Non-empty separator case. 163 // Non-empty separator case.
143 // If the first element is a number then use the heuristic that the 164 // If the first element is a number then use the heuristic that the
144 // remaining elements are also likely to be numbers. 165 // remaining elements are also likely to be numbers.
145 if (!IS_NUMBER(array[0])) { 166 if (!IS_NUMBER(array[0])) {
146 for (var i = 0; i < length; i++) { 167 for (var i = 0; i < length; i++) {
147 var e = array[i]; 168 var e = array[i];
148 if (!IS_STRING(e)) e = convert(e); 169 if (!IS_STRING(e)) e = convert(e);
149 elements[i] = e; 170 elements[i] = e;
150 } 171 }
151 } else { 172 } else {
152 for (var i = 0; i < length; i++) { 173 for (var i = 0; i < length; i++) {
153 var e = array[i]; 174 var e = array[i];
154 if (IS_NUMBER(e)) elements[i] = %_NumberToString(e); 175 if (IS_NUMBER(e)) {
155 else { 176 e = %_NumberToString(e);
156 if (!IS_STRING(e)) e = convert(e); 177 } else if (!IS_STRING(e)) {
178 e = convert(e);
179 }
157 elements[i] = e; 180 elements[i] = e;
158 }
159 } 181 }
160 } 182 }
161 var result = %_FastAsciiArrayJoin(elements, separator); 183 var result = %_FastAsciiArrayJoin(elements, separator);
162 if (!IS_UNDEFINED(result)) return result; 184 if (!IS_UNDEFINED(result)) return result;
163 185
164 return %StringBuilderJoin(elements, length, separator); 186 return %StringBuilderJoin(elements, length, separator);
165 } finally { 187 } finally {
166 // Make sure to remove the last element of the visited array no 188 // Make sure to remove the last element of the visited array no
167 // matter what happens. 189 // matter what happens.
168 if (is_array) visited_arrays.length = visited_arrays.length - 1; 190 if (is_array) visited_arrays.length = visited_arrays.length - 1;
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 InternalArray.prototype.join = getFunction("join", ArrayJoin); 1262 InternalArray.prototype.join = getFunction("join", ArrayJoin);
1241 InternalArray.prototype.pop = getFunction("pop", ArrayPop); 1263 InternalArray.prototype.pop = getFunction("pop", ArrayPop);
1242 InternalArray.prototype.push = getFunction("push", ArrayPush); 1264 InternalArray.prototype.push = getFunction("push", ArrayPush);
1243 InternalArray.prototype.toString = function() { 1265 InternalArray.prototype.toString = function() {
1244 return "Internal Array, length " + this.length; 1266 return "Internal Array, length " + this.length;
1245 }; 1267 };
1246 } 1268 }
1247 1269
1248 1270
1249 SetupArray(); 1271 SetupArray();
OLDNEW
« no previous file with comments | « no previous file | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698