2010-04-10 2 views
4

Предполагая, что мы бежим скомпилированный C++ двоичная:C++ Как быстро проходит объект?

Проходит вокруг int (например, функции к функции, или писать его в переменные) медленнее, чем огибают/Структуры объектов класса как следующий?

class myClass 
{ 
     int a; 
     int b; 
     char c; 
     vector d; 
     string e; 
} 
+1

В общем, передайте по ссылке, чтобы избежать копирования, если размер объекта меньше размера 'void *' или если объект является фундаментальным типом. И если вам когда-нибудь понадобится сделать копию, просто сделайте копию. Для сохранения одной копии не используйте код искажения. C++ 0x вводит семантику перемещения, поэтому ваша копия-версия будет выполняться очень быстро при перемещении в компилятор C++ 0x, если ее можно перенести. Другими словами, просто напишите понятный код, и если производительность когда-либо становится проблемой (через профилирование), вы можете перемещать вещи и редизайн, чтобы избежать копирования. – GManNickG

ответ

7

Это зависит от нескольких факторов, в том числе сложности копирования конструктора и является ли компилятор может сделать elision.

2

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

Однако, если вы передаете фактические объекты (а не указатели на них), вы можете получить копии, сделанные из объектов, что дорого. Однако многие возможные копии могут быть оптимизированы, но это все еще происходит.

3

Каждый раз, когда что-то копируется, сколько времени потребуется, это будет прямым результатом того, насколько велика эта вещь и какие вещи выполняет ее конструктор копирования; очевидно, что класс больше, чем один int, поэтому он будет медленнее. Если вы передаете указатель или передаете предмет по ссылке, копия не требуется, и требуется столько же времени.

+0

Существуют случаи, когда компилятор может удалить копии. Однако он может сделать то же самое для примитивного типа, но дело в том, что количество копий может быть меньше ожидаемого OP. – Omnifarious

0

Это зависит от членов вашего класса.

Обычно вы создаете конструктор копирования, который копирует все необходимые данные в целевой экземпляр вашего класса. Конструктор копирования часто оптимизируется компилятором, поэтому нет никакой разницы между передачей класса с 2-мя int-полями и просто передачей 2-х целых чисел.

2

Передача экземпляра myClass вокруг происходит медленнее, чем передача переменной int, потому что класс инкапсулирует более int. Скорее, вы должны спросить, идет ли прохождение вокруг различных примитивов, составляющих переменные-члены, медленнее, чем передача одного объекта, который обертывает их всех как один. Ответ - нет, два метода должны демонстрировать ту же производительность. В классе нет волшебства: класс просто связывает данные с функциями, если вы попытаетесь выразить это самостоятельно без средств C++, в результате чего вы получите ту же производительность, или, как это может быть больше, - хуже, чем компиляторы C++ уже дают вам.

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

1

Во-первых, многое зависит от того, передаете ли вы объекты по ссылке или по значению.

В C# и Java вы всегда передаете объекты по ссылке, но на C++ вы можете передать копию объекта объекта в стеке (то есть пропущенного значения). Это включает в себя создание физической копии объекта в памяти, что подразумевает пару вызовов конструктора/деструктора (по крайней мере).

Передача int может осуществляться либо по значению, либо по ссылке. Если вы переходите по значению, вы копируете тип int (скажем, 32 bits) в стек.Если вы передаете указатель, вы копируете адрес (опять же, скажем, 32 bits) в стек. На самом деле нет никакой разницы в использовании стека. В случае передачи по ссылке вызывающая функция должна будет разыменовать указатель, чтобы получить доступ к значению параметра int, так что будет некоторый дополнительный код (и, возможно, снижение производительности).

Передача объекта (или структуры) по значению по сравнению с ссылкой более интересна, поскольку они могут имеют очень разные следы памяти (в зависимости от размера класса/структуры).

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