Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Функция reserve()


Автор: IKM2007 30.7.2009, 20:50
Нужно ли всегда использовать функцию reserve() контейнера vector? То есть если просто писать
Код

    std::vector<int> a;

    a.push_back(5);

то виделиться память равную 1Mb? А если писать
Код

    std::vector<int> a;

    a.reserve(100);
    a.push_back(5);

то виделится память равную 100*sizeof(int)? Можно поподробнее о плюсах и о минусах использования функции reserve() ?

Автор: zim22 30.7.2009, 21:06
Цитата(IKM2007 @  30.7.2009,  20:50 Найти цитируемый пост)
 Можно поподробнее о плюсах и о минусах использования функции reserve()

reserve резервирует кусок памяти.
плюсы - если заранее можно просчитать, сколько элементов приблизительно будет в векторе - то можно зарезервировать в самом начале использования этого вектора необходимый объём памяти под элементы. и не будет вызываться функция reallocation'a каждый раз, когда размер вектора будет больше, чем он сможет вместить.
минусы - отнимает у ОС память, которая может не быть использована.
***
вывод: не используйте reserve, если производельность программы вас устраивает.
***
подробнее о reserve в гугле и msdn

Автор: Леопольд 30.7.2009, 21:47
Цитата(IKM2007 @ 30.7.2009,  20:50)
то виделиться память равную 1Mb?

Откуда эта цифра?

Автор: mes 30.7.2009, 21:53
Цитата(zim22 @  30.7.2009,  20:06 Найти цитируемый пост)
вывод: не используйте reserve, если производельность программы вас устраивает.

с выводом не согласен.
 smile 

Автор: andrew_121 30.7.2009, 22:02
Цитата(zim22 @  30.7.2009,  21:06 Найти цитируемый пост)
минусы - отнимает у ОС память, которая может не быть использована.

Так если заранее известно кол-во элементов, значит все равно вектор зарезервирует этот объем памяти. Но при этом потратит больше времени на перевыделение.

Автор: zim22 30.7.2009, 22:09
Цитата(mes @  30.7.2009,  21:53 Найти цитируемый пост)
с выводом не согласен.

надо было уточнить. это мой вывод smile
Цитата(andrew_121 @  30.7.2009,  22:02 Найти цитируемый пост)
Но при этом потратит больше времени на перевыделение.

да, я это и имел ввиду.

Автор: IKM2007 31.7.2009, 12:48
Цитата(Леопольд @  30.7.2009,  21:47 Найти цитируемый пост)
Откуда эта цифра?

Прочитал в инете, было сказано о deque и vector, типа сравнивали, там говорилось, что vector выделяет память по Mb, а deque сколько нужно. То есть оба используют память одинаково?

Добавлено через 5 минут и 37 секунд
Ссылка на тот http://dvinogradov.blogspot.com/2006/03/deque-vs-vector.html. И еще вопрос, по какому принципу выделяется память? То есть ведь оно не выделяется поочередно для каждого элемента, а выделяется блоками, но какими?

Добавлено через 7 минут и 3 секунды
Цитата

1. Меньше overhead. Вектор растет сразу в два раза, а дека - фиксированными страницами. Если храним мегабайт с копейкой, то вектор будет двухмегабайтный, а дека - мегабайт плюс маленький хвостик.

Извиняюсь, не внимательно прочитал. smile 

Автор: azesmcar 31.7.2009, 13:07
Цитата(IKM2007 @  31.7.2009,  12:48 Найти цитируемый пост)
Прочитал в инете, было сказано о deque и vector, типа сравнивали, там говорилось, что vector выделяет память по Mb, а deque сколько нужно. То есть оба используют память одинаково?


Цитата(IKM2007 @  31.7.2009,  12:48 Найти цитируемый пост)
Ссылка на тот ресурс.. 

Там ничего подобного не сказано, там говорится что вектор каждый раз выделяет вдвое больше, чем выделено сейчас. 
Допустим vector<int> при создании по умолчанию выделяет 4000 байтов. Добавим в него 1000 элементов, память исчерпана, при добавлении очередного элемента вектор выделит 8000 байтов памяти а не 4001. Разумеется все эти числа условные, ибо ничего из сказанного не гарантировано, правда многие реализации STL так себя и ведут. Это можно проверить с помощью функции std::vector<T>::capacity().

Автор: IKM2007 31.7.2009, 13:17
azesmcar, но не совсем так у меня получилось. Вот поочередно проверял на сколько элементов выделялась память.
Код

#include <iostream>
#include <vector>
void main()
{
    std::vector<int> a;

    for(int i = 1; i < 100; ++i)
    {
    a.push_back(1);
    std::cout<<"Elements : "<<a.size()<< " => memory : "<<a.capacity()<<"\n";
    }
}

Цитата

Elements : 1 => memory : 1
Elements : 2 => memory : 2
Elements : 3 => memory : 3
Elements : 4 => memory : 4
Elements : 5 => memory : 6
Elements : 6 => memory : 6
Elements : 7 => memory : 9
Elements : 8 => memory : 9
Elements : 9 => memory : 9
Elements : 10 => memory : 13
Elements : 11 => memory : 13
Elements : 12 => memory : 13
Elements : 13 => memory : 13
Elements : 14 => memory : 19
Elements : 15 => memory : 19
Elements : 16 => memory : 19
Elements : 17 => memory : 19
Elements : 18 => memory : 19
Elements : 19 => memory : 19
Elements : 20 => memory : 28
Elements : 21 => memory : 28
Elements : 22 => memory : 28
Elements : 23 => memory : 28
Elements : 24 => memory : 28
Elements : 25 => memory : 28
Elements : 26 => memory : 28
Elements : 27 => memory : 28
Elements : 28 => memory : 28
Elements : 29 => memory : 42
Elements : 30 => memory : 42
Elements : 31 => memory : 42
Elements : 32 => memory : 42
Elements : 33 => memory : 42
Elements : 34 => memory : 42
Elements : 35 => memory : 42
Elements : 36 => memory : 42
Elements : 37 => memory : 42
Elements : 38 => memory : 42
Elements : 39 => memory : 42
Elements : 40 => memory : 42
Elements : 41 => memory : 42
Elements : 42 => memory : 42
Elements : 43 => memory : 63
Elements : 44 => memory : 63
Elements : 45 => memory : 63
Elements : 46 => memory : 63
Elements : 47 => memory : 63
Elements : 48 => memory : 63
Elements : 49 => memory : 63
Elements : 50 => memory : 63
Elements : 51 => memory : 63
Elements : 52 => memory : 63
Elements : 53 => memory : 63
Elements : 54 => memory : 63
Elements : 55 => memory : 63
Elements : 56 => memory : 63
Elements : 57 => memory : 63
Elements : 58 => memory : 63
Elements : 59 => memory : 63
Elements : 60 => memory : 63
Elements : 61 => memory : 63
Elements : 62 => memory : 63
Elements : 63 => memory : 63
Elements : 64 => memory : 94
Elements : 65 => memory : 94
Elements : 66 => memory : 94
Elements : 67 => memory : 94
Elements : 68 => memory : 94
Elements : 69 => memory : 94
Elements : 70 => memory : 94
Elements : 71 => memory : 94
Elements : 72 => memory : 94
Elements : 73 => memory : 94
Elements : 74 => memory : 94
Elements : 75 => memory : 94
Elements : 76 => memory : 94
Elements : 77 => memory : 94
Elements : 78 => memory : 94
Elements : 79 => memory : 94
Elements : 80 => memory : 94
Elements : 81 => memory : 94
Elements : 82 => memory : 94
Elements : 83 => memory : 94
Elements : 84 => memory : 94
Elements : 85 => memory : 94
Elements : 86 => memory : 94
Elements : 87 => memory : 94
Elements : 88 => memory : 94
Elements : 89 => memory : 94
Elements : 90 => memory : 94
Elements : 91 => memory : 94
Elements : 92 => memory : 94
Elements : 93 => memory : 94
Elements : 94 => memory : 94
Elements : 95 => memory : 141
Elements : 96 => memory : 141
Elements : 97 => memory : 141
Elements : 98 => memory : 141
Elements : 99 => memory : 141
Для продолжения нажмите любую клавишу . . .


Автор: azesmcar 31.7.2009, 13:19
IKM2007

Я же говорю, это не гарантировано. Каждый поступает так, как считает нужным. Это похоже на микрософтовскую реализацию.

Вот вывот этой же программы в gcc.
Немного сократил, чтоб не занимать весь экран.
Цитата

Elements : 1 => memory : 1
Elements : 2 => memory : 2
Elements : 3 => memory : 4
Elements : 4 => memory : 4
Elements : 5 => memory : 8
Elements : 6 => memory : 8
Elements : 7 => memory : 8
Elements : 8 => memory : 8
Elements : 9 => memory : 16
Elements : 10 => memory : 16
Elements : 11 => memory : 16
Elements : 12 => memory : 16
Elements : 13 => memory : 16
Elements : 14 => memory : 16
Elements : 15 => memory : 16
Elements : 16 => memory : 16
Elements : 17 => memory : 32
Elements : 18 => memory : 32
Elements : 19 => memory : 32
Elements : 20 => memory : 32
...
Elements : 32 => memory : 32
Elements : 33 => memory : 64
Elements : 34 => memory : 64
Elements : 35 => memory : 64
...
Elements : 64 => memory : 64
Elements : 65 => memory : 128
Elements : 66 => memory : 128
...
Elements : 99 => memory : 128

В этом случае эта тяжелая операция была произведена 8 раз, в случае со студией - 13.

Автор: IKM2007 31.7.2009, 13:27
azesmcar, спасибо, все стало ясно. Вопрос исчерпан.

Автор: W4FhLF 31.7.2009, 15:07
Цитата(IKM2007 @  31.7.2009,  12:48 Найти цитируемый пост)
Прочитал в инете, было сказано о deque и vector, типа сравнивали, там говорилось, что vector выделяет память по Mb, а deque сколько нужно. То есть оба используют память одинаково?


Прочитай Herb Sutter. Решение сложных задач на С++.Exceptional C++ (2002). "Задача 1.14 Использование vector и deque".

В силу своей специфики deque хранит все данные в блоках равного размера и максимум, что выделяет -- это новый блок при необходимости. 

Автор: IKM2007 31.7.2009, 16:10
W4FhLF, прочитал. Теперь вопрос полностью исчерпан. Спасибо. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)