|
|
|
Избыточное копирование объекта при реализации оператора умножения и оператора присваивания21.03.2016, 18:43. Показов 5652. Ответов 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 при выполнении следующего оператора присваивания? Ошибка при выполнении оператора присваивания производного класса через указатель на базовый Ошибка при реализации перегрузки оператора <<
Переопределение оператора присваивания Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
|
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
|
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
|
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
|
|
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время?
Никакой пенсии. Никакого нового. . .
|
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю
Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы
Кратко. . .
|
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем
**Полевые заметки о двухнедельной совместной работе**. . .
|
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики
1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
|