Подтвердить что ты не робот

С++: удаление по сравнению с бесплатным и производительностью

  • Рассмотрим:

    char *p=NULL;
    free(p) // or
    delete p;
    

    Что произойдет, если я использую free и delete на p?

  • Если программа занимает больше времени для выполнения, предположим, 10 минут, есть ли способ сократить время ее работы до 5 минут?

4b9b3361

Ответ 1

Некоторые заметки о производительности для new/delete и malloc/free:

malloc и не не ссылаются на конструктор и деконструктор соответственно. Это означает, что ваши классы не будут автоматически активизироваться или деинициализироваться, что может быть плохим (например, неинициализированные указатели)! Это не имеет значения для типов данных POD, таких как char и двойных, хотя, поскольку у них действительно нет ctor.

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

Я предлагаю оставаться в согласии с использованием нового /malloc, если у вас нет причины (например, realloc). Таким образом, у вас меньше зависимостей, уменьшая размер кода и время загрузки (только с помощью smidgin). Кроме того, вы не будете путаться, освобождая что-то выделенное новым или удаляя что-то, выделенное malloc. (Это скорее всего вызовет сбой!)

Ответ 2

Ответ 1: Оба free(p) и delete p работают нормально с указателем NULL.

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

Ответ 3

Вопрос первый: ничего не произойдет.

Из текущего проекта ИСО/МЭК 14882 (или: С++):

20.8.15 C Library [c.malloc]

Содержимое [из <cstdlib>, то есть: where free lives,] совпадает с библиотекой Standard C [(см. intro.refs для этого)] header <stdlib.h> со следующими изменениями: [ ничего, что влияет на этот ответ].

Итак, из ISO/IEC 9899: 1999 (или: C):

7.20.3.2 Функция free

Если [the] ptr [parameter] - нулевой указатель, никаких действий не происходит.

Из стандарта С++ снова, для информации о delete на этот раз:

3.7.4.2 Функции освобождения [basic.stc.dynamic.deallocation]

Значение первого аргумента, переданного функции освобождения, может быть значением нулевого указателя; если да, и если функция освобождения включена в стандартную библиотеку, вызов не имеет эффекта.

См. также:

Ответ 4

Ничего не произойдет, если вы вызовете бесплатный параметр NULL или удалите его с помощью операнда NULL. Оба определены для принятия NULL и не выполняют никаких действий.

Есть несколько вещей, которые вы можете изменить в коде на С++, который может повлиять на скорость его работы. Часто наиболее полезными (в приблизительном порядке) являются:

  • Используйте хорошие алгоритмы. Это большая тема, но, например, я недавно сократил время выполнения кода немного, используя std::vector вместо std:: list, в том случае, когда элементы добавлялись и удалялись только в конце.
  • Избегайте повторения длинных вычислений.
  • Избегайте создания и копирования объектов без необходимости (но все, что происходит менее 10 миллионов раз в минуту, не будет иметь существенных отличий, если вы не обрабатываете что-то действительно большое, например, вектор из 10 миллионов элементов).
  • Скомпилируйте с оптимизацией.
  • Отметьте общеупотребительные функции (опять-таки, все, что называется более 100 миллионов раз в вашей 10-минутной среде исполнения), как встроенный.

Сказав это, divideandconquer абсолютно прав - вы не можете эффективно ускорить свою программу, если не знаете, что она проводит свое время. Иногда это можно угадать правильно, когда вы знаете, как работает код, а иногда это очень удивительно. Так что лучше всего профилировать. Даже если вы не можете профилировать код, чтобы увидеть, где именно потрачено время, если вы измеряете, какое влияние ваши изменения вы часто можете понять, в конечном итоге.

Ответ 5

В вопросе 2:
Предыдущие ответы отличные. Но я просто хотел добавить что-то о предварительной оптимизации. Предполагая программу средней сложности, правило 90/10 обычно применяется - т.е. 90% времени выполнения расходуется на 10% кода. "Оптимизированный" код часто сложнее читать и поддерживать. Поэтому сначала решайте проблемы, затем посмотрите, где узкие места (профилирование - хороший инструмент).

Ответ 6

Как указывали другие, удаление (или освобождение) указателя NULL ничего не сделает. Однако, если вы выделили некоторую память, то, следует ли использовать free() или delete, зависит от метода, который вы использовали для их распределения. Например, если вы использовали malloc() для выделения памяти, тогда вы должны освободить(), и если вы использовали новое для выделения, вы должны использовать delete. Однако будьте осторожны, чтобы не смешивать распределения памяти. Используйте один способ выделения и освобождения от них.

Во втором вопросе будет очень сложно обобщить, не увидев фактический код. Его следует принимать в каждом конкретном случае.

Ответ 7

Хорошо отвечает на все.

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

Правило 90/10 верно. По моему опыту, обычно есть несколько проблемных точек, и они обычно находятся на уровне уровня стека вызовов. Они часто вызваны использованием более общих структур данных, но вы никогда не должны ничего исправить, если не доказали, что это действительно проблема. Проблемы с производительностью удивительно непредсказуемы.

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

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