что быстрее массив или вектор c
Почему массив намного быстрее, чем вектор?
Это честный тест для сравнения вектора с массивом? Разница в скорости кажется слишком большой. Мой тест показывает, что массив в 10-100 раз быстрее!
Решение
Это зависит от того, что вы сравниваете.
Ваш тест измеряет оба настроить время и доступ раз вместе. Несомненно, что std::vector имеет более дорогое время установки. Это связано с тем, что ему необходимо выделить память, а затем (по необходимости стандарта) вызвать конструкторы по умолчанию для всех элементов. Что для типа POD, означает обнуление.
Так что, если вы пытаетесь измерить время доступа, то ваш эталонный тест не является точным.
Вот некоторые цифры для переваривания:
Оригинальный код:
Время: 444353.5206
Время начала после декларирование и инициализация vector :
Время: 15031.76101
Время: 38129,345
Время примерно одинаковое, независимо от того, приурочено ли объявление. Вероятно, это связано с тем, что выделение стека выполняется сразу после входа в функцию.
По сути, выделение и инициализация векторной памяти занимает непропорциональное количество времени. Но фактический цикл быстрый.
Я также отмечу, что ваша текущая платформа тестов все еще имеет недостатки. Вы делаете только один проход для каждого массива. Так что кеш-эффекты и ленивое размещение будут значительными.
Причина, по которой массив теперь медленнее, вероятно, связана с отложенным размещением. Массив выделен, но он еще не зафиксирован. Ленивое распределение означает, что оно фиксируется при первом доступе, что включает в себя ошибку страницы и переключение контекста в ядро.
Вот более справедливый тест с внешним циклом для увеличения времени теста:
Время: 227330454.6
Время: 212286228.2
Так что нет массива НЕ быстрее, чем вектор для стационарного доступа. Просто сложно правильно оценить.
Что быстрее: или
Что быстрее assembler или c++
Вопрос от новичка. Что будет быстрее по скорости выполнения и на сколько: 1) сложить a+b на C++.
If или switch().case. Что быстрее
Есть два кода. Первый: if(a == 2) a += 2; if(a == 3) a+= 3; if(a == 4) a+=4; Второй:
vector, функция вернет быстрее чем arary
Это разные структуры, статический и динамический массивы.
Гляньте в реализацию, один просто делает
_M_data[n] = item, где некий _M_data это T*
другой же просто делает
_M_data[n] = item, где некий _M_data это T[N]
«Быстрее» что именно. Быстрее делает что именно?
акромя быстрее/медленнее есть исчо кое-что:
Какими же качествами обладает хорошая программа?
Она работает согласно спецификации.
Она сделана в срок.
Ошибки, которые неизбежны, быстро могут быть выявлены и локализованы.
Она хорошо оформлена.
Она решает задачи быстро.
Она имеет дружественный интерфейс.
Очень важное правило: «Программы пишутся для людей, а не для ЭВМ».
Что быстрее: умножение или присваивание
Привет чтобы поменять знак у числа есть два способа. подскажите, который из них будет быстрее.
Что быстрее массив или файл
Привет! Я тут занялся обработкой содержимого текстовых файлов для этого пишу класс отслеживающий.
Деление с остатком или маска, что быстрее?
Всем известно, что побитовый сдвиг ( >) выполняется быстрее деления на два. Деление целых на 2.
Что быстрее работает string или sstream?
Давно уже вижу как используют эти два класса Но какая между ними потенциальная разница? По факту.
Что быстрее, операция присваивания или сравнения?
Всем доброго времени суток, такой вод у меня дурацкий вопрос сидит в голове, «Что быстрее, операция.
В чем разница между вектором и массивом в C++?
В C ++ существует много различий между вектором и массивом. Однако главное сходство очень важно. Основное сходство заключается в том, что оба они представляют собой список, и каждый из них может содержать последовательность данных одного и того же типа. Основные отличия заключаются в следующем: размер (длина) вектора может быть увеличен естественным образом, но размер массива является фиксированным и не может быть увеличен. Элементы могут быть вставлены в вектор, но не могут быть вставлены в массив. Элементы могут быть добавлены в конце вектора, но не могут быть добавлены в конце массива. Вектор — это класс, из которого создаются экземпляры других векторных объектов, но массив является постоянным указателем на последовательность данных того же типа. У вектора есть методы (функции-члены), но у массива их нет, поэтому вектор называется структурой данных. Хотя указатель можно использовать с массивом, итераторы используются с вектором. Итератор — это разработанный указатель.
Перед массивом нельзя включать ни один элемент. В C ++ 17 и выше элемент может быть включен перед вектором с помощью функции-члена emplace ().
В оставшейся части этой статьи проиллюстрированы различия между вектором и массивом. Для каждой точки упоминается недееспособность массива или дается его грубый или громоздкий способ достижения той же цели.
Создание вектора или массива
Вектор можно создать несколькими способами. Основной способ выглядит следующим образом:
Соответственно, массив будет создан следующим образом:
Обратите внимание на разницу в операндах слева от оператора присваивания. Затем количество элементов вектора может быть добавлено или уменьшено, но размер массива остается фиксированным, в данном случае 5.
Чтобы иметь и использовать вектор в программе, программа должна начинаться с:
using namespace std ;
Чтобы иметь и использовать массив в программе, директива препроцессора не требуется.
Увеличение размера
В следующем коде показано, как вектор из изначально двух элементов увеличивается до четырех элементов с помощью его функции-члена push_back ():
Этот код должен быть в теле функции. Для массива, поскольку массив имеет фиксированный размер, создайте массив для максимального количества предусмотренных элементов перед добавлением элементов с помощью оператора []. Пример:
Кроме того, этот код должен находиться внутри тела функции.
Inserting
В следующем коде элемент вставляется перед элементом, на который указывает итератор, p:
for ( int i = ; i vtr. size ( ) ; i ++ ) <
cout vtr [ i ] ‘ ‘ ;
>
Первый оператор кода создает векторный объект. Буква C, которая должна была стоять перед буквой D в алфавитном порядке, здесь отсутствует. Вторая инструкция возвращает итератор, указывающий на первый элемент вектора. Следующие два оператора увеличивают указатель до точки «D». Утверждение после присваивает букву «C» гл. В этом сегменте кода последний оператор вставляет букву «C» перед буквой «D» с помощью итератора.
Что касается массива, то нет возможности вставить элемент. Из-за подобных ограничений для массива были разработаны векторные и другие контейнеры.
Примечание. Функцию-член insert () также можно использовать для вставки элемента перед вектором.
Appending
Добавление означает добавление элементов сзади. Функцию-член push_back () можно использовать для добавления элементов в конец вектора — см. Выше. Массив нельзя добавить. Единственный способ обойти эту проблему для массива — создать массив максимально предусмотренного размера. Вставляйте элементы с самого начала. Тогда в массиве останется некоторое пространство (ячейки). Затем, если есть необходимость добавить элементы сзади, поместите элементы (значения) в пустые пространства позади (со значениями по умолчанию).
Стирание элемента
Для вектора элемент можно стереть с помощью итератора. Затем итератор укажет на следующий элемент, который был там до того, как произошло стирание. Следующий код удаляет букву B:
for ( int i = ; i vtr. size ( ) ; i ++ ) <
cout vtr [ i ] ‘ ‘ ;
>
cout endl ;
cout * q endl ;
Ни один элемент массива нельзя стереть, но его можно изменить.
Clear
Все элементы вектора могут быть удалены с помощью его функции-члена clear () следующим образом:
Используя массивы или std:: vectors в C++, каков разрыв в производительности?
в нашем курсе C++ они предлагают больше не использовать массивы C++ в новых проектах. Насколько я знаю, сам Stroustroup предлагает не использовать массивы. Но есть ли существенные различия в производительности?
17 ответов
использование массивов C++ с new (то есть с использованием динамических массивов) следует избегать. Существует проблема, вы должны отслеживать размер, и вам нужно удалить их вручную, и делать все виды домашнего хозяйства.
использование массивов в стеке также не рекомендуется, потому что у вас нет проверки диапазона, и передача массива вокруг потеряет любую информацию о его размере (преобразование массива в указатель). Вы должны использовать boost::array в этом случае, который обертывает массив C++ в небольшой класс и обеспечивает size функция и итераторы для итерации по нему.
теперь std:: vector против собственных массивов C++ (взято из интернета):
преамбула для людей микро-оптимизатора
«программисты тратят огромное количество времени, думая или беспокоясь о скорости некритических частей своих программ, и эти попытки эффективности на самом деле оказывают сильное негативное влияние при отладке и обслуживании. Мы должны забыть о небольшой эффективности, скажем, о 97% времени:преждевременная оптимизация-корень всех зол. пока мы не должны упускать свои возможности в этих критических 3%».
(спасибо метаморфозы для полной цитаты)
Не используйте массив C вместо вектора (или что-то еще) только потому, что вы считаете, что он быстрее, поскольку он должен быть ниже уровня. Ты ошибаешься.
используйте по умолчанию вектор (или безопасный контейнер, адаптированный к вашим потребностям), а затем, если ваш профилировщик говорит, что это проблема, посмотрите, можете ли вы оптимизировать его, используя лучший алгоритм или изменение контейнера.
об этом сказал, Мы можем вернуться к первоначальному вопросу.
Статический/Динамический Массив?
классы массивов C++ ведут себя лучше, чем низкоуровневый массив C, потому что они много знают о себе и могут ответить на вопросы, которые массивы C не могут. Они способны убирать за собой. И что более важно, они обычно пишутся с использованием шаблонов и / или встраивания, что означает, что то, что кажется многим кодом в debug разрешает мало или нет кода, созданного в сборке выпуска, что не означает разницы с их встроенной менее безопасной конкуренцией.
в целом, он делится на две категории:
динамические массивы
поэтому используйте std:: vector.
статические массивы
использование статического массива будет в лучшем случае:
векторы-это массивы под капотом. Представление то же самое.
одно место, где вы можете столкнуться с проблемой производительности, не правильно определяет размер вектора для начала.
по мере заполнения вектора он будет изменять размер, и это может означать новое распределение массива, за которым следуют N конструкторов копирования, а затем около n вызовов деструктора, а затем удаление массива.
Если ваша конструкция / деструкт стоит дорого, вам намного лучше сделать вектор правильный размер для начала.
существует простой способ продемонстрировать это. Создайте простой класс, который показывает, когда он построен/уничтожен/скопирован / назначен. Создайте вектор этих вещей и начните толкать их на заднем конце вектора. Когда вектор заполняется, будет каскад активности по мере изменения размера вектора. Затем повторите попытку с вектором, размер которого равен ожидаемому количеству элементов. Вы увидите разницу.
ответить на что-то Мехрдад сказал:
однако могут быть случаи, когда вам все еще нужны массивы. Когда взаимодействие с кодом низкого уровня (т. е. сборка) или старые библиотеки, которые требовать массивы, возможно, вы не сможете использовать векторы.
вообще не верно. Векторы красиво деградируют в массивы / указатели, если вы используете:
это работает для всех основных реализаций STL. В следующем стандарте это будет требуется для работы (хотя сегодня это просто отлично).
у вас еще меньше причин использовать простые массивы в C++11.
есть 3 вида массивов в природе от самого быстрого до самого медленного, в зависимости от особенностей, которые они имеют (конечно, качество реализации может сделать вещи очень быстро даже для случая 3 в списке):
на 1. простые статические массивы с фиксированным количеством элементов, используйте std::array в C++11.
на 2. массивы фиксированного размера, указанные во время выполнения, но это не изменит их размер, есть обсуждение в C++14, но он был перемещен в техническая спецификация и сделанный из C++14 окончательно.
на 3. std::vector обычно запрашивает память в куче. Это может иметь последствия для производительности, хотя вы можете использовать std::vector > для улучшения ситуации с пользовательский распределитель. Преимущество по сравнению с T mytype[] = new MyType[n]; заключается в том, что вы можете изменить его размер и что он не будет распадаться на указатель, как простые массивы делать.
используйте стандартные типы библиотек, упомянутые, чтобы избежать массивы распадаясь на указатели. Вы сэкономите время отладки и производительность ровно то же самое, что и с обычными массивами, если вы используете тот же набор функций.
STL-сильно оптимизированная библиотека. Фактически, даже предлагается использовать STL в играх, где может потребоваться высокая производительность. Массивы слишком подвержены ошибкам для использования в повседневных задачах. Сегодняшние компиляторы также очень умны и могут действительно производить отличный код с STL. Если вы знаете, что делаете, STL обычно может обеспечить необходимую производительность. Например, инициализируя векторы до требуемого размера (если вы знаете с самого начала), вы можете в основном достичь производительности массива. Однако могут быть случаи, когда вам все еще нужны массивы. При взаимодействии с низкоуровневым кодом (т. е. сборкой) или старыми библиотеками, требующими массивов, вы не сможете использовать векторы.
перейти с STL. Нет никакого штрафа за производительность. Алгоритмы очень эффективны, и они хорошо справляются с деталями, о которых большинство из нас не думает.
вывод заключается в том, что массивы целых чисел быстрее, чем векторы целых чисел (в моем примере 5 раз). Однако массивы и векторы имеют одинаковую скорость для более сложных / не выровненных данных.
Если вы компилируете программное обеспечение в режиме отладки, многие компиляторы не будут вставлять функции доступа вектора. Это сделает реализацию вектора stl намного медленнее в условиях, когда производительность является проблемой. Это также облегчит отладку кода, так как вы можете видеть в отладчике, сколько памяти было выделено.
в оптимизированном режиме я ожидал бы, что вектор stl приблизится к эффективности массива. Это так много методов векторной сейчас встроенный.
пока вы сравниваете яблоки с яблоками (либо массив, либо вектор имеют фиксированное количество элементов, либо оба изменяются динамически), я бы подумал, что разница в производительности незначительна, пока вы следуете got STL практика кодирования. Не забывайте, что использование стандартных контейнеров c++ также позволяет использовать предварительно свернутые алгоритмы, которые являются частью стандартной библиотеки C++, и большинство из них, вероятно, будут лучше работать, чем средняя реализация того же алгоритма, который вы создаете сами.
тем не менее, IMHO вектор выигрывает в сценарии отладки с debug STL, поскольку большинство реализаций STL с правильным режимом отладки могут по крайней мере выделить / cathc типичные ошибки, сделанные людьми, когда работа со стандартными контейнерами.
О, и не забывайте, что массив и вектор имеют одинаковый макет памяти, поэтому вы можете использовать векторы для передачи данных в устаревший код C или C++, который ожидает базовые массивы. Имейте в виду, что большинство ставок в этом сценарии отключены, и вы снова имеете дело с необработанной памятью.
существует определенно влияние производительности на использование std::vector против необработанного массива, когда вы хотите неинициализированные буфер (например, использовать в качестве назначения для memcpy() ). Ан std::vector инициализирует все его элементы с помощью конструктора по умолчанию. Необработанный массив не будет.
на в C++ спецификаций на std:vector конструктор принимая
Если вам не нужно динамически регулировать размер, у вас есть накладные расходы памяти для сохранения емкости (один указатель/size_t). Вот и все.
Я бы сказал, что главная забота не производительность, а безопасность. Вы можете сделать много ошибок с массивами (например, рассмотреть изменение размера), где вектор сэкономит вам много боли.
следующий простой тест:
противоречит выводам из » сравнения кода сборки, сгенерированного для базовых операций индексирования, разыменования и приращения векторов и массивов/указателей.»
там должна быть разница между массивами и векторами. Так написано в тесте. просто попробуйте, код есть.
иногда массивы действительно лучше, чем векторы. Если ты всегда манипулируешь набор объектов фиксированной длины, массивы лучше. Рассмотрим следующие фрагменты кода:
где векторная версия X является
и версия массива X:
версия массива будет main() будет быстрее, потому что мы избегаем накладные расходы «нового» каждый раз во внутреннем цикле.
(этот код был размещен в компания.ленг.C++ by me).
Используя массивы или std :: vectors в C ++, какова разница в производительности?
В нашем курсе C ++ они предлагают больше не использовать массивы C ++ в новых проектах. Насколько я знаю, сам Stroustroup предлагает не использовать массивы. Но есть ли существенные различия в производительности?
Использование массивов C ++ с new Следует избегать использования массивов (то есть динамических массивов). Есть проблема, вы должны следить за размером, и вам нужно удалить их вручную и сделать все виды домашнего хозяйства.
Использование массивов в стеке также не рекомендуется, поскольку у вас нет проверки диапазона, и передача массива потеряет любую информацию о его размере (преобразование массива в указатель). Вы должны использовать boost::array в этом случае, который оборачивает массив C ++ в небольшой класс и обеспечивает size функцию и итераторы для его перебора.
Теперь std :: vector против собственных массивов C ++ (взятых из Интернета):
Преамбула для микрооптимизаторов
(Благодаря метаморфозам за полную цитату)
Не используйте массив C вместо вектора (или чего-либо еще) только потому, что вы считаете, что он быстрее, так как предполагается, что он более низкого уровня. Ты был бы неправ.
Используйте вектор по умолчанию (или безопасный контейнер, адаптированный к вашим потребностям), и затем, если ваш профилировщик скажет, что это проблема, посмотрите, можете ли вы оптимизировать его, либо используя лучший алгоритм, либо изменив контейнер.
Тем не менее, мы можем вернуться к первоначальному вопросу.
Статический / Динамический Массив?
Классы массива C ++ ведут себя лучше, чем низкоуровневый массив C, потому что они много знают о себе и могут отвечать на вопросы, а массивы C не могут. Они умеют убирать за собой. И что еще более важно, они обычно пишутся с использованием шаблонов и / или встраивания, что означает, что то, что кажется для большого количества кода в отладке, разрешается в виде небольшого или нулевого кода, созданного в сборке релиза, что означает отсутствие различий с их встроенной менее безопасной конкуренцией.
В целом, это падает на две категории:
Динамические массивы
Использование указателя на массив malloc-ed / new-ed будет в лучшем случае таким же быстрым, как версия std :: vector, и намного менее безопасным (см. Сообщение от litb). ).
Так что используйте std :: vector.
Статические массивы
Использование статического массива будет в лучшем случае:
Неинициализированная память
Единственное место, где вы можете столкнуться с проблемой производительности, это не правильно выбрать вектор для начала.
Когда вектор заполняется, он меняет свой размер, что может означать новое выделение массива, за которым следуют n конструкторов копирования, за которыми следуют около n вызовов деструктора, а затем удаление массива.
Если ваша конструкция / деструктор дорогая, вам лучше сделать вектор правильного размера для начала.
Есть простой способ продемонстрировать это. Создайте простой класс, который показывает, когда он создается / уничтожается / копируется / назначается. Создайте вектор этих вещей и начните помещать их в конец вектора. Когда вектор заполнится, произойдет каскад активности при изменении размера вектора. Затем попробуйте снова с вектором, размер которого соответствует ожидаемому количеству элементов. Вы увидите разницу.
Чтобы ответить на что-то, Мердад сказал:
Однако могут быть случаи, когда вам все еще нужны массивы. При взаимодействии с кодом низкого уровня (т. Е. Сборкой) или старыми библиотеками, которым требуются массивы, вы не сможете использовать векторы.
Совсем не правда. Векторы хорошо разлагаются на массивы / указатели, если вы используете:
Это работает для всех основных реализаций STL. В следующем стандарте он будет работать (хотя сегодня он работает нормально).
У вас еще меньше причин использовать простые массивы в C ++ 11.
В природе существует 3 вида массивов, от самых быстрых до самых медленных, в зависимости от имеющихся у них функций (конечно, качество реализации может сделать вещи действительно быстрыми даже для случая 3 в списке):
Для 1. простых статических массивов с фиксированным числом элементов используйте std::array в C ++ 11.
За 2. массивов фиксированного размера, указанных во время выполнения, но это не изменит их размера, есть обсуждение в C ++ 14, но оно было перенесено в техническую спецификацию и наконец сделано из C ++ 14.