Skip to content
Browse files
Setting the value of a textarea is much slower in WebKit than it is i…
…n Chromium

Reviewed by Alexey Proskuryakov.

These changes make the micro-benchmark of setting the text of a textarea about 4x faster.

* Source/WTF/wtf/text/StringView.cpp:
(WTF::makeStringBySimplifyingNewLinesSlowCase): Added. Implements a faster algorithm for
standardizing line endings as opposed to making two passes through the string.

* Source/WTF/wtf/text/StringView.h:
(WTF::makeStringBySimplifyingNewLines): Added a high-speed check for '\r' characters before doing
the slower algorithm to standardize line separators. Most strings won't have any at all, and none
of the ones in the benchmark do.

Canonical link:
  • Loading branch information
darinadler committed Nov 12, 2022
1 parent c048bf2 commit 610bbdbf42f2cad4bb6a06eadd3e6fcc735cc59b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
@@ -447,6 +447,35 @@ int codePointCompare(StringView lhs, StringView rhs)
return codePointCompare(lhs.characters16(), lhs.length(), rhs.characters16(), rhs.length());

template<typename CharacterType> static String makeStringBySimplifyingNewLinesSlowCase(const String& string, unsigned firstCarriageReturn)
unsigned length = string.length();
unsigned resultLength = firstCarriageReturn;
auto* characters = string.characters<CharacterType>();
CharacterType* resultCharacters;
auto result = String::createUninitialized(length, resultCharacters);
memcpy(resultCharacters, characters, firstCarriageReturn * sizeof(CharacterType));
for (unsigned i = firstCarriageReturn; i < length; ++i) {
if (characters[i] != '\r')
resultCharacters[resultLength++] = characters[i];
else {
resultCharacters[resultLength++] = '\n';
if (i < length + 1 && characters[i + 1] == '\n')
if (resultLength < length)
result = StringImpl::createSubstringSharingImpl(*result.impl(), 0, resultLength);
return result;

String makeStringBySimplifyingNewLinesSlowCase(const String& string, unsigned firstCarriageReturn)
if (string.is8Bit())
return makeStringBySimplifyingNewLinesSlowCase<LChar>(string, firstCarriageReturn);
return makeStringBySimplifyingNewLinesSlowCase<UChar>(string, firstCarriageReturn);


// Manage reference count manually so UnderlyingString does not need to be defined in the header.
@@ -1356,10 +1356,14 @@ inline String WARN_UNUSED_RETURN makeStringByReplacingAll(const String& string,

WTF_EXPORT_PRIVATE String WARN_UNUSED_RETURN makeStringByReplacingAll(StringView, UChar target, UChar replacement);
WTF_EXPORT_PRIVATE String WARN_UNUSED_RETURN makeStringBySimplifyingNewLinesSlowCase(const String&, unsigned firstCarriageReturnOffset);

inline String WARN_UNUSED_RETURN makeStringBySimplifyingNewLines(const String& string)
return makeStringByReplacingAll(makeStringByReplacingAll(string, "\r\n"_s, "\n"_s), '\r', '\n');
auto firstCarriageReturn = string.find('\r');
if (firstCarriageReturn == notFound)
return string;
return makeStringBySimplifyingNewLinesSlowCase(string, firstCarriageReturn);

inline bool String::startsWith(StringView string) const

0 comments on commit 610bbdb

Please sign in to comment.