mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 04:12:43 +00:00 
			
		
		
		
	LibJS+AK: Make String.prototype.repeat() way faster
Instead of using a StringBuilder, add a String::repeated(String, N)
overload that takes advantage of knowing it's already all UTF-8.
This makes the following microbenchmark go 4x faster:
    "foo".repeat(100_000_000)
And for single character strings, we can even go 10x faster:
    "x".repeat(100_000_000)
			
			
This commit is contained in:
		
							parent
							
								
									9ce267944c
								
							
						
					
					
						commit
						a285e36041
					
				
					 3 changed files with 21 additions and 4 deletions
				
			
		|  | @ -636,4 +636,21 @@ bool String::equals_ignoring_ascii_case(StringView other) const | ||||||
|     return StringUtils::equals_ignoring_ascii_case(bytes_as_string_view(), other); |     return StringUtils::equals_ignoring_ascii_case(bytes_as_string_view(), other); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | String String::repeated(String const& input, size_t count) | ||||||
|  | { | ||||||
|  |     VERIFY(!Checked<size_t>::multiplication_would_overflow(count, input.bytes().size())); | ||||||
|  |     u8* buffer = nullptr; | ||||||
|  |     auto data = MUST(Detail::StringData::create_uninitialized(count * input.bytes().size(), buffer)); | ||||||
|  | 
 | ||||||
|  |     if (input.bytes().size() == 1) { | ||||||
|  |         memset(buffer, input.bytes().first(), count); | ||||||
|  |         return String { move(data) }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < count; ++i) { | ||||||
|  |         memcpy(buffer + (i * input.bytes().size()), input.bytes().data(), input.bytes().size()); | ||||||
|  |     } | ||||||
|  |     return String { data }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -92,6 +92,9 @@ public: | ||||||
|     // Creates a new String with a single code point repeated N times.
 |     // Creates a new String with a single code point repeated N times.
 | ||||||
|     static ErrorOr<String> repeated(u32 code_point, size_t count); |     static ErrorOr<String> repeated(u32 code_point, size_t count); | ||||||
| 
 | 
 | ||||||
|  |     // Creates a new String from another string, repeated N times.
 | ||||||
|  |     static String repeated(String const&, size_t count); | ||||||
|  | 
 | ||||||
|     // Creates a new String by case-transforming this String. Using these methods require linking LibUnicode into your application.
 |     // Creates a new String by case-transforming this String. Using these methods require linking LibUnicode into your application.
 | ||||||
|     ErrorOr<String> to_lowercase(Optional<StringView> const& locale = {}) const; |     ErrorOr<String> to_lowercase(Optional<StringView> const& locale = {}) const; | ||||||
|     ErrorOr<String> to_uppercase(Optional<StringView> const& locale = {}) const; |     ErrorOr<String> to_uppercase(Optional<StringView> const& locale = {}) const; | ||||||
|  |  | ||||||
|  | @ -777,10 +777,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat) | ||||||
|         return PrimitiveString::create(vm, String {}); |         return PrimitiveString::create(vm, String {}); | ||||||
| 
 | 
 | ||||||
|     // 6. Return the String value that is made from n copies of S appended together.
 |     // 6. Return the String value that is made from n copies of S appended together.
 | ||||||
|     StringBuilder builder; |     return PrimitiveString::create(vm, String::repeated(string, n)); | ||||||
|     for (size_t i = 0; i < n; ++i) |  | ||||||
|         builder.append(string); |  | ||||||
|     return PrimitiveString::create(vm, MUST(builder.to_string())); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 22.1.3.19 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
 | // 22.1.3.19 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling