Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/75: Рейтинг темы: голосов - 75, средняя оценка - 4.91
0 / 0 / 2
Регистрация: 24.06.2012
Сообщений: 112

Что быстрее списки или вектор ?

08.06.2017, 19:36. Показов 14316. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Делаю приложение и очень важна скорость обработки данных, а нужно хранить динамические массивы.
В каком формате будет поэлементный перебор происходить быстрее? В частности нужно хранить комплексные числа.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.06.2017, 19:36
Ответы с готовыми решениями:

Что быстрее: i++ или ++i ?
Только что прочитала в интернете, что префиксный итератор быстрее, чем постфиксный. Так ли это? Если так и если в С++ все есть обьект, то...

Почему матрица на вектор умножается быстрее чем вектор на матрицу?
Почему матрица на вектор умножается быстрее чем вектор на матрицу?

Что быстрее assembler или c++
Вопрос от новичка. Что будет быстрее по скорости выполнения и на сколько: 1) сложить a+b на C++ или на assembler 2) умножить a*b на C++...

36
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
08.06.2017, 19:42
про скорость не знаю а мне больше вектор по душе, хотя и списки тоже хороши,
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
08.06.2017, 19:58
Лучший ответ Сообщение было отмечено Leffken как решение

Решение

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

Так что если требуется пройтись по каждому из элементов по очереди (не прыгая между ними) то лучше список, а если прыгать необходимо - то вектор.

Промежуточный вариант - хэш-таблица адресов (когда изобретаем формулу вычисления адреса элемента по его номеру, но так, чтобы между элементами было достаточно много пустого места, чтобы при необходимости можно было повставлять перед/за ним какое-то число элементов без необходимости двигать всю структуру).

Добавлено через 6 минут
А ещё есть деревья (т.е. когда из одного элемента доступно сразу несколько следующих ), по "характеристикам" - промежуточное положение между списком и хэш-таблицей .
1
53 / 31 / 13
Регистрация: 21.05.2017
Сообщений: 109
08.06.2017, 20:44
TRam_, ведя разговор о списках, необходимо помнить, что его быстрая вставка и удалени - это лишь теория. Постоянное дерганье узлов списка выльется в постоянные кеш-промахи и отнимет кучу процессорного времени. Запомни, vector - хорошо дружит с кешем, т.к. он непрерывен. Что касается копирований и т.д., то во-первых, есть перемещение, во-вторых, вставка в конец вектора, скорее всего, обгонит список в разы, а в-третьих, каждая вставка в список требует аллоцировать память, у вектора же запас.

Что касается выбора контейнера, то отталкиваться нужно совсем не от теоретической его скорости. Сначала необходимо решить какие контейнеры на вообще подойдут. Например, нам нужен контейнер, итераторы на элементы которого не будут инвалидироваться. Тогда вектор нам сразу не подойдет, однако, если вставка только в конец и нам известно максимальное число элементов, которое нам потребуется, то, нам подойдет и вектор, но с предварительным резервированием (но всё же ассерт лучше добавить, для проверки).
А точную скорость, которую нам даст вектор или список нужно проверять на конкретном наборе данных и оборудовании. Все остальные замеры будут не верными, возможно, даже противоположными. Так что берите и тестируйте.
3
0 / 0 / 2
Регистрация: 24.06.2012
Сообщений: 112
09.06.2017, 09:09  [ТС]
Цитата Сообщение от MasterOfAlteran Посмотреть сообщение
Что касается выбора контейнера, то отталкиваться нужно совсем не от теоретической его скорости. Сначала необходимо решить какие контейнеры на вообще подойдут. Например, нам нужен контейнер, итераторы на элементы которого не будут инвалидироваться. Тогда вектор нам сразу не подойдет, однако, если вставка только в конец и нам известно максимальное число элементов, которое нам потребуется, то, нам подойдет и вектор, но с предварительным резервированием (но всё же ассерт лучше добавить, для проверки).
Планируется хранить в памяти N -ое кол-во наборов (как бы двумерный массив) комплексных чисел. Из функционала полный перебор всех элементов, вставка в конец, размер не известен. И да, скорее всего надо будет иметь обращение к соседним элементам, так что доступ по индексу хотелось бы осуществлять. Поэтому выбор в сторону вектора. Надеюсь хватит скорости )) Если что придется параллелить.
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
09.06.2017, 09:16
Цитата Сообщение от Leffken Посмотреть сообщение
Надеюсь хватит скорости
у флеша попросите тогда будет моментально выполняться а так много факторов могут повлиять на скорость
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
09.06.2017, 11:28
Цитата Сообщение от Leffken Посмотреть сообщение
В каком формате будет поэлементный перебор происходить быстрее?
В векторе т.к. он гарантирует, что элементы будут располагаться один за другим. Список же располагает элементы в произвольном порядке в памяти.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
09.06.2017, 11:51
MrGluck,
А можно подробнее? Не могу понять, в чем разница. На мой взгляд скорость будет одинаковой т.к в итоге в обоих случаях все сводится к адрес-> данные
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
09.06.2017, 12:05
Undisputed, нет, в случае списка нужно смотреть значение указателя чтобы взять адрес следующей ячейки. Для вектора же достаточно брать одинаковое смещение при проходе, компилятору это дело проще обрабатывать.
1
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
09.06.2017, 12:11
Цитата Сообщение от Undisputed Посмотреть сообщение
На мой взгляд скорость будет одинаковой т.к в итоге в обоих случаях все сводится к адрес-> данные
В случае списка для того чтоб добраться к n-ому элементу нужно n раз произвести операцию адрес->данные. В случае вектора нужно произвести простое умножение размера элемента на n, чтобы получить смещение к данным, и, прибавив адрес нулевого, получить требуемый адрес n-ого. И после этого единственный раз произвести адрес->данные.
1
 Аватар для Celly
158 / 148 / 25
Регистрация: 23.01.2011
Сообщений: 319
09.06.2017, 12:15
Если планируется хранения большого количества элементов, то стоит учитывать что при использовании std::list будут дополнительные расходы памяти, в размере двух указателей на соседние элементы для каждого элемента списка.

Undisputed,
Если вам необходимо хранить динамический массив (из вашего описания, только для добавления), то я бы вам посоветовал посмотреть ещё в сторону std::deque т.к. он в специфику своей реализации позволит избежать перераспределений памяти в долгосрочной перспективе. Память в std::deque выделяется постранично, и в случае нехватки памяти в странице, будет выделена новая и связана как тот же двусвязный список.

Но, опять же, пока ещё никто не отменял std::vector::reserve().

Чтобы окончательно определиться с контейнером, необходимо больше информации о задаче.
Ещё есть одно хорошее правило: "Если вы не знаете какой контейнер выбрать, выбирайте std::vector"
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
09.06.2017, 13:26
Цитата Сообщение от Celly Посмотреть сообщение
Если планируется хранения большого количества элементов, то стоит учитывать что при использовании std::list будут дополнительные расходы памяти, в размере двух указателей на соседние элементы для каждого элемента списка.
А при использовании вектора не будет? Его push_back должен работать за амортизированное константное время. Но при push_back может случиться реаллокация данных которая, понятное дело, работает за линейное время (на перекидывание данных с места на место). Чтобы скрестить первое со вторым, надо минимизировать число реаллокаций. А значит хапать память с этак 100% запасом.
1
 Аватар для Celly
158 / 148 / 25
Регистрация: 23.01.2011
Сообщений: 319
09.06.2017, 13:39
Цитата Сообщение от Renji Посмотреть сообщение
А при использовании вектора не будет? Его push_back должен работать за амортизированное константное время. Но при push_back может случиться реаллокация данных которая, понятное дело, работает за линейное время (на перекидывание данных с места на место). Чтобы скрестить первое со вторым, надо минимизировать число реаллокаций. А значит хапать память с этак 100% запасом.
Не будет. Здесь речь идёт о дополнительной памяти которую будут занимать служебные данные контейнера. У std::vector служебных данных несколько байт. У std::list - по 2 указателя на каждый элемент, т.е. при использовании списка на каждый элемент будет ещё приходится 8 байт (на 32 битной системе) служебных данных. Renji, дальше вашу мысль не понял.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.06.2017, 13:41
Цитата Сообщение от Renji Посмотреть сообщение
Но при push_back может случиться реаллокация
При удалении элементов тоже не лучше. Всё переписывается уже в выделенной области иначе без переиндексации (тех же указателей) чтобы получить прямой доступ с семантикой последовательного размещения не получится. То есть затраты. Зато список на стенку пи не умеет бинари сёрчить по человечески. То есть, даже в сортированном списке нужно в среднем N/2 шагов. А в векторе двоичный логарифм. То есть, искать тем проще чем больше объём. Вектору хорошо, если его заполняют однажды и потом только читают. Или, по крайней мере, не часто заставляют релоцировать.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
09.06.2017, 13:42
Цитата Сообщение от Celly Посмотреть сообщение
Renji, дальше вашу мысль не понял.
C++
1
2
3
4
5
6
void push_back(const T&val)
{
    if(size()==capacity())
        reserve(size()*2);//опаньки, вот и дополнительные расходы памяти
    new(_data+_size++) T(val);
}
0
 Аватар для Celly
158 / 148 / 25
Регистрация: 23.01.2011
Сообщений: 319
09.06.2017, 13:51
Renji, В вашем примере происходит выделение памяти, которая в последсвии будет использоваться для хранения элементов. В случае std::list идёт речь о памяти которая будет использоваться для служебных данных самой структуры std::list. Это размер двух указателей для каждого элемента списка. Допустим, в данной задаче, размер комплексного числа 8 байт (4 байта действительная часть и 4 мнимая). Тогда, на каждый элемент списка размером 8 байт придётся ещё 8 байт служебных данных (по 4 байта на указатели на соседние элементы).
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
09.06.2017, 13:55
Цитата Сообщение от Celly Посмотреть сообщение
Не будет.
Будет-будет. Список не релоцируется вообще. А вектор, - да релоцируется. Конечно, если сравнивать неизменяемые контейнеры равного объёма данных, то вектор меньше. Это правда. Но в реальной жизни, неизменяемость это то, что делает применение списка бессмысленным и сравнение тоже теряет смысл. Иначе, если только есть такая возможность, то список удобнее. Память сегодня не самое узкое место.
К тому же есть хеш-массивы которые используют плохие качества и массивов и списков.
Вот одна ужасная фантазия на тему:
https://www.cyberforum.ru/blog... g4772.html
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
09.06.2017, 13:56
Цитата Сообщение от Celly Посмотреть сообщение
Renji, В вашем примере происходит выделение памяти, которая в последсвии будет использоваться для хранения элементов.
Кто вам сказал что эта память будет использоваться?
C++
1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
#include<vector>
 
int main()
{
    std::vector<double> test;
    for(int i=0;i<10;++i)
        test.push_back(i);
    std::cout<<"и "<<test.capacity()-test.size()<<" из "<<test.capacity()<<
               " позиций висят мертвым грузом"<<std::endl;
}
Итог - "и 6 из 16 позиций висят мертвым грузом".
0
 Аватар для Celly
158 / 148 / 25
Регистрация: 23.01.2011
Сообщений: 319
09.06.2017, 14:08
IGPIGP, Перечитайте мои посты. Вы пытаетесь присвоить мне суждение о том что память вектора не перераспределяется.
Я говорил о том что в случае std::vector дополнительный расход памяти на служебные данных контейнера минимален. В случае std::list - в размере двух указателей на каждый элемент.

Добавлено через 4 минуты
Renji, В момент вывода на экран - да, не используются. Но вы можете так же уверенно заявить что в процессе жизни программы они не будут использоваться?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
09.06.2017, 14:14
Цитата Сообщение от Celly Посмотреть сообщение
Renji, В момент вывода на экран - да, не используются. Но вы можете так же уверенно заявить что в процессе жизни программы они не будут использоваться?
Не я, а теория вероятности может заявить, что в среднем половина этого резерва будет пустовать. Но, разумеется, это в среднем. Так то у вас есть отличный от нуля шанс что вектор всегда будет полностью использовать занятую "про запас" память. Просто этот шанс стремится к нулю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.06.2017, 14:14
Помогаю со студенческими работами здесь

Что быстрее: умножение или присваивание
Привет чтобы поменять знак у числа есть два способа. подскажите, который из них будет быстрее работать double var = 6.0; var *=...

Что быстрее массив или файл
Привет! Я тут занялся обработкой содержимого текстовых файлов для этого пишу класс отслеживающий положение курсора в файле (типа номер...

If или switch().case. Что быстрее
Есть два кода. Первый: if(a == 2) a += 2; if(a == 3) a+= 3; if(a == 4) a+=4; Второй:

Что быстрее - двоичный или текстовый файл?
Встал вопрос о времени чтения данных с диска, посему нужно выбрать быстрейший из этих двух способов хранения данных на внешнем носителе. ...

Что быстрее, операция присваивания или сравнения?
Всем доброго времени суток, такой вод у меня дурацкий вопрос сидит в голове, &quot;Что быстрее, операция присваивания или сравнения?&quot;. Вот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru