2013-12-12 2 views
-1

Если бы я выделил много (GBS) памяти с помощью:C++ выделяет недостатки памяти?

int N = ...; 
int * array_ = new int[N]; 

и использовать дробь из массива, какого рода недостаток этого метода имеет, кроме того очевидного факта, я трачу память? Это влияет на производительность процессора или делает работу нестабильной?

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

+2

Вектор не дает массивного удара производительности – deeiip

+0

Почему бы вам не сравнить свой метод с использованием вектора? – Sash

+0

Ну, это дает, потому что при добавлении нового элемента векторный класс копирует все данные массива в новый массив и затем удаляет старый массив. В некоторых случаях контрольные показатели показывают как минимум 50% -ный удар, 100%. – SkyRipper

ответ

5

В зависимости от того, как ОС и (возможно) программа реагирует на нехватке памяти, теряя память может сделать программу медленным или неустойчивым. Никаких гарантий.

На современной ОС большой, но в основном неиспользуемый динамический массив int должен иметь очень мало или вообще не оказывать никакого воздействия. Большая часть неиспользуемой части массива будет только когда-либо назначена виртуальная память, она никогда не будет поддерживаться оперативной памятью или свопом. 64-разрядные операционные системы (которые вы должны использовать, если вы говорите о 32 ГБ ОЗУ) не будут содержать виртуального адресного пространства, пока вы не воспользуетесь этими байтами 2 .

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

Там, вероятно, большой хит производительности для создания vector<int> больше, чем вам нужно, так как он будет инициализирован в то время как этот массив не инициализирован. Если это то, что вы имеете в виду, тогда ваш код не должен вызывать больше нестабильности, чем огромный вектор, и, возможно, меньше, потому что память никогда не затрагивается.

Если это не так, то не должно быть большого удара производительности от вектора с включенной оптимизацией. Таким образом, вы можете, например, обойти его, используя вектор struct UninitializedInt { int value; UninitializedInt() {} };, чтобы обеспечить конструкцию по умолчанию no-op. Возможно, вы захотите добавить конструктор int и/или operator int(), чтобы облегчить жизнь пользователя (запретите набирать номер .value повсюду), хотя это приводит к двусмысленным арифметическим операциям, поэтому это не шлейф.

Или, возможно, вы могли бы использовать reserve() выделить место для вектора, а затем resize() или push_back()insert() или по мере необходимости. Если это закончится тем, что вы действительно проверяете границы или изменяете размер при каждом доступе, вы просто замените один удар производительности другим, конечно.

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

std::unique_ptr<int[]> array_(new int[N]); 
+0

Правильно, мое плохое. Я читал это совершенно неправильно. –

0

Единственный действительно надежный способ узнать это - фактически сделать это и выполнить тесты производительности. Попробуйте сделать все это, как вы думаете, и сравнить и сравнить на основе реальных данных, записанных в этих реальных тестах. Но в стороне, образованная догадка заключается в том, что вы сильно переоцениваете хит производительности std::vector.

4

И используйте часть массива, какой недостаток этот метод имеет, кроме очевидного факта, я теряю память? Это влияет на производительность процессора или делает работу нестабильной?

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

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

Это неверно в любой респектабельной реализации C++. std::vector имеет нулевые накладные расходы. Компилятор лучше оптимизирован, чем вы, и может встроить функции-члены и многое другое.


Что касается Вашего комментария:

Ну, это дает, потому что при добавлении нового элемента копий вектора класса все данные массива в новый массив, а затем удаляет старый массив. В некоторых случаях контрольные показатели показывают как минимум 50% -ный удар, 100%.

См. std::vector::reserve.

+0

+1 для «в любой респектабельной реализации C++. Std :: vector имеет нулевые служебные данные. Компилятор лучше оптимизирован, чем вы» – deeiip

+1

«std :: vector» имеет нулевые служебные данные »в этом прецеденте неверно. Мой ответ содержит описание больших накладных расходов. –

0

Это уже было адресовано here.

И вот ответ:

Это всегда лучше использовать станд :: вектор/зЬй :: массив, по крайней мере, пока вы не может убедительно доказать (путем профилирования), что Т * а = новый T [100]; решение значительно быстрее в вашей конкретной ситуации. Это маловероятно: вектор/массив - чрезвычайно тонкий слой вокруг обычного простого массива . Есть некоторые накладные расходы на проверку границ с помощью vector :: at, но вы можете обойти это с помощью оператора [].

0

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

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

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

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