Что я могу сделать, чтобы улучшить этот поиск в векторе указателей?

Моя цель - проверить вектор Person* на предмет Person с именем person_name. Вектор отсортирован по именам в алфавитном порядке. Создание временного Person - единственный способ заставить этот вызов lower_bound работать с именем. Есть ли более эффективный способ сделать это или нужен temp для проведения сравнений?

//person_name is a string
Person temp(person_name);
auto it = lower_bound(personVec.begin(), personVec.end(), &temp, personCompare());
if (it != personVec.end() && (*it)->getName() == person_name) {}
else { return false;  }

Если вы собираетесь часто использовать поисковые имена, я бы посоветовал unordered_map. Если нет, то зачем беспокоиться о поиске чего-то другого, когда то, что у вас есть, работает? Поместите его в вспомогательную функцию и забудьте о нем, если вы не профилируете, и это узкое место.

Retired Ninja 06.09.2018 06:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

temp не нужен. Вам нужен компаратор с соответствующей подписью.

Например, при разыменовании результатов personVec.begin() с помощью Person*& а person_name имеет тип PersonName, тогда у вас может быть компаратор с такой сигнатурой:

bool compare(Person* const& a, PersonName const& b);

Вот простая функция, но подойдут и другие вызываемые объекты с такой подписью. Затем вы можете использовать lower_bound напрямую с person_name:

auto it = lower_bound(personVec.begin(), personVec.end(), person_name, compare);

Ваш общий вопрос был о том, как повысить производительность. Это невозможно предположить, увидев 4 строчки программы. Это должно быть выяснено путем профилирования всей программы при большой загрузке данных и анализа результатов. Например, сортировка personVec может занять больше времени, чем сортировка lower_bound. Тогда использование unordered_set вместо vector может дать гораздо лучшие результаты, чем оптимизация функции поиска в vector.

unordered_map выглядит правильным, но я не уверен в реализации. <Person*, string> Я установил его с помощью хэш-функции и функции равенства. find() использует первый параметр шаблона (ключ), как и хэш и равенство, но я хочу выполнить поиск по входному person_name, а затем получить итератор на указатель, и я смогу сделать это без temp. Не могли бы вы уточнить? @ Пенсионер ниндзя
Rez 06.09.2018 11:04

Я должен уточнить: я исследую unordered_map, потому что читал, что он может быть полезен для того, что я пытаюсь сделать, но я буду использовать unordered_set, если этого достаточно.

Rez 06.09.2018 11:29

Вы делали профилирование готового безупречного продукта с большой загрузкой данных? В противном случае правильный способ - внедрить продукт и забыть о производительности до того, как он станет полностью правильным, а затем профилировать его и выполнять работы по производительности. Только тогда вы знаете, что вам нужно в этом unordered_set<P,H,K,A> или unordered_map<S,P,H,K,A> или любом другом контейнере. Не используйте «Я хочу», используйте «Мне нужно, потому что ...» (заполните пробел). Например, P, должно ли быть Person *, а не Person? Вам нужно, чтобы экземпляр Person был изменяемым или динамически полиморфным?

Öö Tiib 06.09.2018 12:29

Перед тем, как перейти к этому шагу, я убедился, что результаты верны. Причина, по которой я использую Person* для вектора, заключается в том, что я создаю программу-график с Person в качестве типа узла, и мне нужна реализация, аналогичная этой [stackoverflow.com/a/44859718/5181816], чтобы иметь доступ ко всем узлам и выполнять несколько задач, пока они доступны, например, соединение и перемещение.

Rez 06.09.2018 19:19

Думаю, я понял это: unordered_map<string, Person*> Это позволяет ему выполнять find() в строке, а затем итератор дает доступ к Person с it->second.

Rez 06.09.2018 19:45

Другие вопросы по теме