Changeset 28782 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Dec 16, 2007, 5:14:36 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/array_instance.cpp
r28468 r28782 50 50 static const unsigned minDensityMultiplier = 8; 51 51 52 static const unsigned mergeSortCutoff = 10000;52 static const unsigned copyingSortCutoff = 50000; 53 53 54 54 const ClassInfo ArrayInstance::info = {"Array", 0, 0}; … … 430 430 } 431 431 432 static int compareByStringPairForQSort(const void* a, const void* b) 433 { 434 const std::pair<JSValue*, UString>* va = static_cast<const std::pair<JSValue*, UString>*>(a); 435 const std::pair<JSValue*, UString>* vb = static_cast<const std::pair<JSValue*, UString>*>(b); 436 return compare(va->second, vb->second); 437 } 438 432 439 static ExecState* execForCompareByStringForQSort = 0; 433 434 440 static int compareByStringForQSort(const void* a, const void* b) 435 441 { … … 448 454 unsigned lengthNotIncludingUndefined = compactForSorting(); 449 455 456 if (lengthNotIncludingUndefined < copyingSortCutoff) { 457 // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that. 458 // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary 459 // buffer. For large arrays, we fall back to a qsort on the JavaScriptValues to avoid creating copies. 460 461 Vector<std::pair<JSValue*, UString> > values(lengthNotIncludingUndefined); 462 for (size_t i = 0; i < lengthNotIncludingUndefined; i++) { 463 JSValue* value = m_storage->m_vector[i]; 464 ASSERT(!value->isUndefined()); 465 values[i].first = value; 466 values[i].second = value->toString(exec); 467 } 468 469 // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather 470 // than O(N log N). 471 472 #if HAVE(MERGESORT) 473 mergesort(values.begin(), values.size(), sizeof(std::pair<JSValue*, UString>), compareByStringPairForQSort); 474 #else 475 qsort(values.begin(), values.size(), sizeof(std::pair<JSValue*, UString>), compareByStringPairForQSort); 476 #endif 477 for (size_t i = 0; i < lengthNotIncludingUndefined; i++) 478 m_storage->m_vector[i] = values[i].first; 479 return; 480 } 481 450 482 ExecState* oldExec = execForCompareByStringForQSort; 451 483 execForCompareByStringForQSort = exec; 452 453 #if HAVE(MERGESORT)454 // Because mergesort usually does fewer compares, it is faster than qsort here.455 // However, because it requires extra copies of the storage buffer, don't use it for very456 // large arrays.457 458 // FIXME: Since we sort by string value, a fast algorithm might be to convert all the459 // values to string once up front, and then use a radix sort. That would be O(N) rather460 // than O(N log N).461 462 if (lengthNotIncludingUndefined < mergeSortCutoff) {463 // During the sort, we could do a garbage collect, and it's important to still464 // have references to every object in the array for ArrayInstance::mark.465 // The mergesort algorithm does not guarantee this, so we sort a copy rather466 // than the original.467 size_t size = storageSize(m_vectorLength);468 ArrayStorage* copy = static_cast<ArrayStorage*>(fastMalloc(size));469 memcpy(copy, m_storage, size);470 mergesort(copy->m_vector, lengthNotIncludingUndefined, sizeof(JSValue*), compareByStringForQSort);471 fastFree(m_storage);472 m_storage = copy;473 execForCompareByStringForQSort = oldExec;474 return;475 }476 #endif477 478 484 qsort(m_storage->m_vector, lengthNotIncludingUndefined, sizeof(JSValue*), compareByStringForQSort); 479 485 execForCompareByStringForQSort = oldExec; … … 529 535 // better job of minimizing compares. 530 536 531 if (lengthNotIncludingUndefined < mergeSortCutoff) {537 if (lengthNotIncludingUndefined < copyingSortCutoff) { 532 538 // During the sort, we could do a garbage collect, and it's important to still 533 539 // have references to every object in the array for ArrayInstance::mark.
Note:
See TracChangeset
for help on using the changeset viewer.