2013-03-26 3 views
3

Я читаю некоторые сегменты линии из cin. Каждый сегмент линии представлен начальной и конечной точкой. 2D. X и Y.std: sort vs inserting into std :: set

Вход не отсортирован. Это в случайном порядке. (Обновление: но мне они сначала отсортированы по X, а затем по Y)

Я могу читать во всех сегментах, хранить их в векторе, а затем вызывать std :: sort. С другой стороны, я могу создать пустой std :: set и вставить каждый сегмент по мере его поступления. Набор автоматически сохранит отсортированный порядок. Какой из двух подходов более эффективен?

Обновление: общий размер ввода (количество сегментов) известен заранее.

+0

@larsmans благодарит за исправление. Проводка из бара. ;) –

+6

Почему бы вам просто не попробовать? Реальные данные о производительности> «что сказал мне какой-то парень из интернетов» – jalf

+2

@jalf Я думал, что это старый вопрос с общепринятым ответом. Кроме того, сколько различных наборов входных данных следует попробовать до принятия решения? –

ответ

10

Вы должны измерить производительность обоих подходов, чтобы быть уверенным, но это безопасная ставка, чтобы предположить, что std::sort на std::vector является способ быстрее, чем вставка в std::set из-за локальности эффектов и больших констант, скрывающихся в дереве алгоритм вставки. Кроме того, последующие запросы и итерация будут выполняться быстрее.

(Тем не менее, std::set лучше подходит для поддержки смешанного ряда вставок и делеции/выборок/итераций. Поддержание порядка в векторе является дорогостоящим, поскольку каждая вставка будет принимать линейное время в среднем.)

+2

О, правда? Почему это так? –

+1

От чего это зависит? –

+6

@LightnessRacesinOrbit: константы в вставке деревьев довольно высоки (подумайте о перебалансировке в красно-черном дереве) по сравнению с теми, которые хорошо оптимизированы. –

3

Используй контейнер который имеет соответствующую семантику для ваших нужд. Эффективность обычно следует автоматически с этого выбора.

Если вы затем испытываете узкие места в производительности, выполните некоторые бенчмаркинга.

+0

Мне нужно, чтобы я мог перемещаться по входу слева направо. В случае, если два входа имеют одинаковый x, выигрыш меньше. –

+2

+1: семантика первая, исполнение второе. –

+0

@AgnelKurian Если для ваших данных нет встроенного заказа, используйте набор. Это куча вещей, втиснутых в сумку. Как приятный побочный эффект, вы получаете лексикографическое (или что вам нужно), заказывающее его при повторении, поэтому, если вы хотите, чтобы это было в конце, это тоже удобно. –

4

Это действительно зависит, но он уверен, что std::set предназначен для случайных вставок и стираний. В этом случае вы только вставляете. Идите с std::vector. Кроме того, возможно, что более важно, если вы заранее знаете, сколько сегментов есть, вам нужно всего лишь выделить вектор только один раз, он не будет перераспределять память каждый раз, когда он удваивается по размеру.

8

Как хорошее эмпирическое правило, предлагаются более строгие гарантии, тем хуже производительность.

Вставка в std::set гарантирует, что последовательность сортируется после каждой вставки.

Вставка в std::vector, и призывая std::sortраз после все вставки были сделаны гарантии, что последовательность сортируется раз все манипуляции на vector были сделаны. Это не требует, чтобы вектор был отсортирован во время всех промежуточных вставок.

A std::vector также обладает лучшей пространственной локальностью и требует меньшего выделения памяти. Таким образом, я бы предположил, что подход vector будет быстрее, но если для вас важна производительность, то это имеет значение, чтобы быть измеряется.

Если вы не заботитесь, чтобы измерить то, что быстрее в вашем случае для ваших наборов данных с вашего кода в вашего приложения, то вам не все равно, что быстрее.

Смежные вопросы