|
|
|
Избыточное копирование объекта при реализации оператора умножения и оператора присваивания21.03.2016, 18:43. Показов 5621. Ответов 84
Метки нет (Все метки)
Есть класс работы с матрицами. Есть операция умножения матриц, описанная как оператор класса. В данном коротком примере я просто моделирую ситуацию. Реальное наполнение класса принципиальной разницы не играет, нужно просто понимать, что оператор умножения будет иметь большой код, оператор присваивания в реализации тоже будет не пустым. Эти места в примере засвечены комментариями
C++ #include <cstdio> class Matrix { private: // внутренние данные матрицы public: Matrix (); Matrix (const Matrix&); ~Matrix (); Matrix& operator=(const Matrix& a); Matrix operator*(const Matrix& a) const; }; Matrix::Matrix () { printf ("Matrix ()\n"); }; Matrix::Matrix (const Matrix&) { printf ("Matrix (const Matrix&)\n"); }; Matrix::~Matrix () { printf ("~Matrix ()\n"); }; Matrix& Matrix::operator=(const Matrix& a) { printf ("operator=(const Matrix&)\n"); // тут как бы код, копирущий данные из "a" в "this" return *this; } Matrix Matrix::operator*(const Matrix& a) const { printf ("operator*(const Matrix&)\n"); Matrix result; // тут как бы код, умножающий "a" и "this" и записывающий // данные в "result" return result; } Matrix a, b, c; int main (void) { printf ("------------------\n"); a = b * c; printf ("------------------\n"); } Code $ g++-4.8 t.cc $ ./a.out Matrix () Matrix () Matrix () ------------------ operator*(const Matrix&) Matrix () operator=(const Matrix&) ~Matrix () ------------------ ~Matrix () ~Matrix () ~Matrix () Посмотрим на ассемблерный код. Компилирую с опцией -fno-inline, чтобы оставаться с короткой программой и не разводить геморрой по борьбе с inline'ом со стороны компилятора. В общем случае тела операторов класса Matrix будут в отдельном файле и НЕ будут доступны для inline'а. Опцию -fno-exceptions подаю, чтобы было меньше мусора в коде Code $ g++ t.cc -O2 -fno-inline -fno-exceptions $ cat t.s ... leal -9(%ebp), %ebx subl $32, %esp movl %ebx, (%esp) movl $c, 8(%esp) movl $b, 4(%esp) call _ZN6MatrixmlERKS_ <- operator* subl $4, %esp movl %ebx, 4(%esp) movl $a, (%esp) call _ZN6MatrixaSERKS_ <- operator= ... C typedef struct { /* внутренности */ } Matrix; extern void operator_assign (Matrix *this, const Matrix *value); extern void operator_mul (Matrix *result, const Matrix *this, const Matrix *operand2); Matrix a, b, c; int main (void) { Matrix tmp; operator_mul (&tmp, &b, &c); /* tmp = b.operator* (c) */ operator_assign (&a, &tmp); /* a.operator= (tmp) */ } C operator_mul (&a, &b, &c); Вопрос. Как правильно написать текст на C++, чтобы получить код, эквивалентный вышеприведённой эффективной реализации на C? Оставаясь при этом в объёме стандарта C++98. Оставляя исходник в понятном и читабельном виде, без использования извращений типа семиэтажных шаблонов и т.п.
0
|
|
| 21.03.2016, 18:43 | |
|
Ответы с готовыми решениями:
84
Неправильная работа оператора присваивания после работы оператора суммирования От каких ошибок страхует Const при перегрузке оператора присваивания
|
| 22.03.2016, 15:02 | |
|
Не по теме: Renji, если вы используете матрицу 2x2, которая заполняется сразу("за раз"),
0
|
|
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||
| 22.03.2016, 15:26 | ||
|
Evg,
1
|
||
|
|
|||||
| 22.03.2016, 15:46 [ТС] | |||||
|
Во всяком случае твоя претензия помогла мне интуитивно понять, почему "стандартными средствами C++" мою постановку задачи В ОБЩЕМ СЛУЧАЕ не решить без промежуточного копирования
0
|
|||||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||
| 22.03.2016, 15:55 | ||
|
В общем случае - тут тернарная операция, и реализовать ее как две бинарных - не получится. Исходя из вышесказанного: Matrix::inplace_mul(const Matrix& l, const Matrix& r) так, наверное.
0
|
||
|
|
|||||||
| 22.03.2016, 15:56 | |||||||
a, для которого уже будет вызвать *=. b тут меняться не будет.
0
|
|||||||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 22.03.2016, 16:04 | |
|
Evg, В принципе можно возвращать из
operator* кортеж {Matrix*, Matrix*} и в operator=(std::tuple реализовать умножение. В общем возвращать прокси.
0
|
|
|
|
|||||
| 22.03.2016, 16:26 [ТС] | |||||
|
0
|
|||||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||
| 22.03.2016, 16:33 | ||
0
|
||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
||||
| 22.03.2016, 16:43 | ||||
|
Nosey, а ты зачем считаешь кол-во инструкций? Типа меньше инструкций - быстрее программа?
![]()
0
|
||||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 22.03.2016, 16:48 | |
|
ct0r, Как показывает практика, когда речь заходит о перемножении матриц - минимум тактов не крайность, а необходимость.
0
|
|
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 22.03.2016, 17:01 | |
|
0
|
|
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|
| 22.03.2016, 17:05 | |
|
0
|
|
|
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
|
|||||||||||||
| 22.03.2016, 17:06 | |||||||||||||
А ты его запускал свой конкретный пример?Ну ладно, открывай ротик, закладываю :
Результаты : 99999999 3105052 - cpp 99999999 3098734 - c И да, это расчёты честные, никаких компайлтайм расчётов нету. А вы считаете, что в данном случае меньшее количество инструкций хуже работают?
0
|
|||||||||||||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
||
| 22.03.2016, 17:16 | ||
|
Компилятор, когда оптимизирует, на кол-во инструкций точно не смотрит.
0
|
||
|
|
|||
| 22.03.2016, 17:26 [ТС] | |||
|
C++ a = b * c; C operator_mul (&a, &b, &c); Добавлено через 9 минут Правда я всё равно не понимаю, что ты мне продемонстрировать этим примером хочешь. Если хочешь продемонстрировать, что ненужные копирования занимают всего 1% (2%, 3%, не суть) от времени исполнения, то мне это вовсе не интересно. Если для выполнения какой-то задачи код должен быть быстрым, то борьба идёт за каждый процент времени исполнения
0
|
|||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|
| 22.03.2016, 17:28 | |
|
Evg, ну ООП в С++ тогда тоже некультурно, потому что в стиле Smalltalk. А перегрузка операторов - потому что в стиле ALGOL.
0
|
|
|
|
||
| 22.03.2016, 17:29 [ТС] | ||
|
0
|
||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 22.03.2016, 17:43 | |
|
0
|
|
| 22.03.2016, 17:43 | |
|
Какое значение получит переменная p при выполнении следующего оператора присваивания? Ошибка при выполнении оператора присваивания производного класса через указатель на базовый Ошибка при реализации перегрузки оператора <<
Переопределение оператора присваивания Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
|
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
|
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал.
Оно само - говорит.
Кто слышит тот слышит.
|
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было
ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась.
Первый вариант. . .
|
|
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2.
Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
|
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет.
Но обычно это 50 лет и более.
Наверное, закисление почвы происходит сезонно в средней. . .
|
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
|
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS
Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
|