Skip to content

Commit 171e03d

Browse files
solomonwzstordex
authored andcommitted
Optimizing remove_whitespace performance
fix #397
1 parent d7d23e1 commit 171e03d

File tree

1 file changed

+59
-4
lines changed

1 file changed

+59
-4
lines changed

src/css_parser.cpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,48 @@ void filter_code_points(string& input)
3838
input = result;
3939
}
4040

41-
void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
41+
static const size_t kLargeSize = 50;
42+
static void remove_whitespace_large(css_token_vector& tokens, keep_whitespace_fn keep_whitespace);
43+
static void remove_whitespace_small(css_token_vector& tokens, keep_whitespace_fn keep_whitespace);
44+
45+
void remove_whitespace_large(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
46+
{
47+
std::vector<int> keep_idx;
48+
keep_idx.reserve(tokens.size());
49+
for (int i = 0; i < static_cast<int>(tokens.size()); ++i)
50+
{
51+
auto &tok = tokens[i];
52+
bool keep = true;
53+
if (tok.type == ' ')
54+
{
55+
const auto &left = i > 0 ? tokens[i - 1] : css_token();
56+
const auto &right = at(tokens, i + 1);
57+
keep = keep_whitespace && keep_whitespace(left, right);
58+
}
59+
else if (tok.is_component_value())
60+
{
61+
if (tok.value.size() > kLargeSize)
62+
remove_whitespace_large(tok.value, keep_whitespace);
63+
else
64+
remove_whitespace_small(tok.value, keep_whitespace);
65+
}
66+
if (keep)
67+
keep_idx.push_back(i);
68+
}
69+
70+
if (keep_idx.size() == tokens.size())
71+
return;
72+
else
73+
{
74+
css_token_vector tmp;
75+
tmp.reserve(keep_idx.size());
76+
for (auto idx : keep_idx)
77+
tmp.push_back(tokens[idx]);
78+
tokens.swap(tmp);
79+
}
80+
}
81+
82+
void remove_whitespace_small(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
4283
{
4384
for (int i = 0; i < (int)tokens.size(); i++)
4485
{
@@ -48,13 +89,27 @@ void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitesp
4889
const auto& left = i > 0 ? tokens[i - 1] : css_token();
4990
const auto& right = at(tokens, i + 1);
5091
bool keep = keep_whitespace && keep_whitespace(left, right);
51-
if (!keep) remove(tokens, i), i--;
92+
if (!keep)
93+
remove(tokens, i), i--;
5294
}
5395
else if (tok.is_component_value())
54-
remove_whitespace(tok.value, keep_whitespace);
96+
{
97+
if (tok.value.size() > kLargeSize)
98+
remove_whitespace_large(tok.value, keep_whitespace);
99+
else
100+
remove_whitespace_small(tok.value, keep_whitespace);
101+
}
55102
}
56103
}
57104

105+
void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
106+
{
107+
if (tokens.size() > kLargeSize)
108+
remove_whitespace_large(tokens, keep_whitespace);
109+
else
110+
remove_whitespace_small(tokens, keep_whitespace);
111+
}
112+
58113
void componentize(css_token_vector& tokens)
59114
{
60115
css_parser parser(tokens);
@@ -511,4 +566,4 @@ bool skip_whitespace(const css_token_vector& tokens, int& index)
511566
return index != start;
512567
}
513568

514-
} // namespace litehtml
569+
} // namespace litehtml

0 commit comments

Comments
 (0)