Commit 1adc373e authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Improve performance of FindFormControlElementsByUniqueRendererId

Before this CL, FindFormControlElementsByUniqueRendererId did many
linear searches over its vector parameter |form_control_renderer_ids|,
and accordingly had a DCHECK that the vector doesn't contain more than
10 elements.
This CL changes the implementation to build and use a map instead for
the lookups, thus avoiding the linear searches, and making
FindFormControlElementsByUniqueRendererId appropriate for larger
inputs.

Bug: 1004777
Change-Id: I0699d87de7202f42269c3504ecf08356ee880601
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1899455Reviewed-by: default avatarVadym Doroshenko <dvadym@chromium.org>
Commit-Queue: Marc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712552}
parent 5da6c653
......@@ -2164,23 +2164,24 @@ WebFormControlElement FindFormControlElementsByUniqueRendererId(
std::vector<WebFormControlElement> FindFormControlElementsByUniqueRendererId(
WebDocument doc,
const std::vector<uint32_t>& form_control_renderer_ids) {
DCHECK_LE(form_control_renderer_ids.size(), 10u)
<< "More effective look-up should be implemented";
WebElementCollection elements = doc.All();
std::vector<WebFormControlElement> result(form_control_renderer_ids.size());
// Build a map from entries in |form_control_renderer_ids| to their indices,
// for more efficient lookup.
std::map<uint32_t, size_t> renderer_id_to_index;
for (size_t i = 0; i < form_control_renderer_ids.size(); i++)
renderer_id_to_index[form_control_renderer_ids[i]] = i;
for (WebElement element = elements.FirstItem(); !element.IsNull();
element = elements.NextItem()) {
if (!element.IsFormControlElement())
continue;
WebFormControlElement control = element.To<WebFormControlElement>();
auto it = std::find(form_control_renderer_ids.begin(),
form_control_renderer_ids.end(),
control.UniqueRendererFormControlId());
if (it == form_control_renderer_ids.end())
auto it = renderer_id_to_index.find(control.UniqueRendererFormControlId());
if (it == renderer_id_to_index.end())
continue;
size_t index = std::distance(form_control_renderer_ids.begin(), it);
result[index] = control;
result[it->second] = control;
}
return result;
......@@ -2190,23 +2191,24 @@ std::vector<WebFormControlElement> FindFormControlElementsByUniqueRendererId(
WebDocument doc,
uint32_t form_renderer_id,
const std::vector<uint32_t>& form_control_renderer_ids) {
DCHECK_LE(form_control_renderer_ids.size(), 10u)
<< "More effective look-up should be implemented";
std::vector<WebFormControlElement> result(form_control_renderer_ids.size());
WebFormElement form = FindFormByUniqueRendererId(doc, form_renderer_id);
if (form.IsNull())
return result;
// Build a map from entries in |form_control_renderer_ids| to their indices,
// for more efficient lookup.
std::map<uint32_t, size_t> renderer_id_to_index;
for (size_t i = 0; i < form_control_renderer_ids.size(); i++)
renderer_id_to_index[form_control_renderer_ids[i]] = i;
WebVector<WebFormControlElement> fields;
form.GetFormControlElements(fields);
for (const auto& field : fields) {
auto it = std::find(form_control_renderer_ids.begin(),
form_control_renderer_ids.end(),
field.UniqueRendererFormControlId());
if (it == form_control_renderer_ids.end())
auto it = renderer_id_to_index.find(field.UniqueRendererFormControlId());
if (it == renderer_id_to_index.end())
continue;
size_t index = std::distance(form_control_renderer_ids.begin(), it);
result[index] = field;
result[it->second] = field;
}
return result;
}
......
......@@ -295,8 +295,6 @@ blink::WebFormControlElement FindFormControlElementsByUniqueRendererId(
// Returns form control elements by unique renderer id. The result has the same
// number elements as |form_control_renderer_ids| and i-th element of the result
// corresponds to the i-th element of |form_control_renderer_ids|.
// |form_control_renderer_ids| is supposed to be small (<=10 elements), because
// it is being frequently searched by linear pass over its elements.
// The call of this function might be time expensive, because it retrieves all
// DOM elements.
std::vector<blink::WebFormControlElement>
......@@ -308,8 +306,6 @@ FindFormControlElementsByUniqueRendererId(
// id |form_renderer_id|. The result has the same number elements as
// |form_control_renderer_ids| and i-th element of the result corresponds to the
// i-th element of |form_control_renderer_ids|.
// |form_control_renderer_ids| is supposed to be small (<=10 elements), because
// it is being frequently searched by linear pass over its elements.
// This function is faster than the previous one, because it only retrieves form
// control elements from a single form.
std::vector<blink::WebFormControlElement>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment