mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 18:20:43 +09:00
LibJS: Cache the Intl.Collator in String.prototype.localeCompare()
In the very common case that no special constructor options are provided for the Intl.Collator when calling localeCompare() on a string, we can cache and reuse a default-constructed Intl.Collator, saving lots of time and space. This shaves a fair bit of load time off of https://wpt.fyi/ where they use Array.prototype.sort() and localeCompare() to sort a big JSON thing. Time spent in sort(): - Before: 1656 ms - After: 135 ms
This commit is contained in:
parent
65c1c492f9
commit
d465e2aa2b
Notes:
github-actions[bot]
2025-01-23 20:39:21 +00:00
Author: https://github.com/awesomekling
Commit: d465e2aa2b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3347
3 changed files with 26 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2020-2025, Andreas Kling <andreas@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
#include <LibJS/Runtime/GeneratorFunctionConstructor.h>
|
#include <LibJS/Runtime/GeneratorFunctionConstructor.h>
|
||||||
#include <LibJS/Runtime/GeneratorFunctionPrototype.h>
|
#include <LibJS/Runtime/GeneratorFunctionPrototype.h>
|
||||||
#include <LibJS/Runtime/GeneratorPrototype.h>
|
#include <LibJS/Runtime/GeneratorPrototype.h>
|
||||||
|
#include <LibJS/Runtime/Intl/Collator.h>
|
||||||
#include <LibJS/Runtime/Intl/CollatorConstructor.h>
|
#include <LibJS/Runtime/Intl/CollatorConstructor.h>
|
||||||
#include <LibJS/Runtime/Intl/CollatorPrototype.h>
|
#include <LibJS/Runtime/Intl/CollatorPrototype.h>
|
||||||
#include <LibJS/Runtime/Intl/DateTimeFormatConstructor.h>
|
#include <LibJS/Runtime/Intl/DateTimeFormatConstructor.h>
|
||||||
|
@ -418,6 +420,16 @@ void Intrinsics::visit_edges(Visitor& visitor)
|
||||||
visitor.visit(m_##snake_name##_prototype);
|
visitor.visit(m_##snake_name##_prototype);
|
||||||
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
|
visitor.visit(m_default_collator);
|
||||||
|
}
|
||||||
|
|
||||||
|
GC::Ref<Intl::Collator> Intrinsics::default_collator()
|
||||||
|
{
|
||||||
|
if (!m_default_collator) {
|
||||||
|
m_default_collator = as<Intl::Collator>(*MUST(construct(this->vm(), intl_collator_constructor(), js_undefined(), js_undefined())));
|
||||||
|
}
|
||||||
|
return *m_default_collator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10.2.4 AddRestrictedFunctionProperties ( F, realm ), https://tc39.es/ecma262/#sec-addrestrictedfunctionproperties
|
// 10.2.4 AddRestrictedFunctionProperties ( F, realm ), https://tc39.es/ecma262/#sec-addrestrictedfunctionproperties
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
|
* Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2020-2025, Andreas Kling <andreas@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -95,6 +96,8 @@ public:
|
||||||
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
|
[[nodiscard]] GC::Ref<Intl::Collator> default_collator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Intrinsics(Realm& realm)
|
Intrinsics(Realm& realm)
|
||||||
: m_realm(realm)
|
: m_realm(realm)
|
||||||
|
@ -189,6 +192,8 @@ private:
|
||||||
GC::Ptr<Object> m_##snake_name##_prototype;
|
GC::Ptr<Object> m_##snake_name##_prototype;
|
||||||
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
|
GC::Ptr<Intl::Collator> m_default_collator;
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_restricted_function_properties(FunctionObject&, Realm&);
|
void add_restricted_function_properties(FunctionObject&, Realm&);
|
||||||
|
|
|
@ -544,7 +544,15 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare)
|
||||||
auto that_value = TRY(vm.argument(0).to_string(vm));
|
auto that_value = TRY(vm.argument(0).to_string(vm));
|
||||||
|
|
||||||
// 4. Let collator be ? Construct(%Collator%, « locales, options »).
|
// 4. Let collator be ? Construct(%Collator%, « locales, options »).
|
||||||
auto collator = TRY(construct(vm, realm.intrinsics().intl_collator_constructor(), vm.argument(1), vm.argument(2)));
|
auto locales = vm.argument(1);
|
||||||
|
auto options = vm.argument(2);
|
||||||
|
|
||||||
|
// OPTIMIZATION: If both locales and options are undefined, we can use a cached default-constructed Collator.
|
||||||
|
GC::Ptr<Object> collator;
|
||||||
|
if (locales.is_undefined() && options.is_undefined())
|
||||||
|
collator = realm.intrinsics().default_collator();
|
||||||
|
else
|
||||||
|
collator = TRY(construct(vm, realm.intrinsics().intl_collator_constructor(), locales, options));
|
||||||
|
|
||||||
// 5. Return CompareStrings(collator, S, thatValue).
|
// 5. Return CompareStrings(collator, S, thatValue).
|
||||||
return Intl::compare_strings(static_cast<Intl::Collator const&>(*collator), string, that_value);
|
return Intl::compare_strings(static_cast<Intl::Collator const&>(*collator), string, that_value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue