C++ выделяет недостатки памяти?

Если бы я выделил много (ГБ) памяти, используя:

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

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

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

5 ответов

Решение

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

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

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

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

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

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

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

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

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

Ваш код будет сложно поддерживать и исключать небезопасно. (Да, будет. Нет, правда.)

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

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


По поводу вашего комментария:

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

Увидеть std::vector::reserve,

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

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

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

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

Это уже было решено здесь.

И вот ответ:

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

Другие вопросы по тегам