Russian Qt Forum
Апрель 27, 2024, 08:21 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4 5 6   Вниз
  Печать  
Автор Тема: оператор [] для union  (Прочитано 36216 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #30 : Май 06, 2018, 12:43 »

Рискну утверждать что это не только не костыль, но такая задача является типовой.

Есть контейнеры 3 (тех же) типов
Код
C++ (Qt)
Container<double> c1;
Container<coordinate> c2;
Container<color> c3;
Которые имеют массу общего (могут рисоваться в виде графиков, отображаться в таблицах и.т.п.).
А вот и причина. Улыбающийся
Попытка бизнес-логику притянуть к Gui, чего делать категорически нельзя.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #31 : Май 06, 2018, 13:19 »

К вопросу о производительности boost::variant vs union

Приаттачиваю проект с аналогом CData - MData на variantе.

Результаты такие (при numSamples = 100000 * 1024;):
Код
Bash
igors: Total time (sec) = 29
m_ax: Total time (sec) = 39
 

Выводы делайте сами)

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #32 : Май 07, 2018, 12:28 »

Выводы делайте сами)

boost/std::variant  - тормозное поделие? Улыбающийся Зачем нужна вся эта ваша меташаблонная магия, если простой унылый свитч работает в полтора раза быстрее )).

Но если разбираться, то разница в CData и MData состоит в том, что в первом классе методы GetNth/SetNth инлайнятся, а во втором в визитёре вызывается функция и она не инлайнится. Собственно, если в CData написать:
Код
C++ (Qt)
double GetNth(size_t index) const __attribute__((noinline))
...
double SetNth(size_t index) const __attribute__((noinline))
...
то тормозить он будет также, как и MData. И если из MData выкинуть getNth/setNth и переписать операторы нормально, чтобы они работали с массивами целиком, а не поэлементно дёргали, то и скорость его приблизится к CData.

variant - универсальный класс, CData - частичная наколенная реализация. Если в CData добавить универсальность, проверки и исключения, то тормозить он будет как variant, И наоборот, для частного случая variant можно написать быструю частную версию visit/apply.

Но дело даже не в этом. Igors, Вы арифметические операторы для координат и цвета засунули в CData. Если понадобится что-то сделать с координатой или цветом, которые есть отдельно, не в CData, Вы код (а главное логику операторов) будете дублировать или как? Что мешает написать  нормальные классы координат и цвета, определить для них операции и использовать их в variant, раз уж вляпались в него? Вопрос слегка риторический, можно не отвечать Улыбающийся.
Записан

Пока сам не сделаешь...
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #33 : Май 07, 2018, 13:50 »

Цитировать
Но дело даже не в этом.
Тут как ввсегда всё дело в непродуманной и кривой архитектуре.. Впрочем, ничего нового  Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #34 : Май 08, 2018, 10:16 »

Зачем нужна вся эта ваша меташаблонная магия, если простой унылый свитч работает в полтора раза быстрее )).
Хоть бы и в два, такая разница не крытычна. Гораздо важнее что удается отделаться простейшими средствами - и это не ведет к громадному уродливому коду (сравните объемы реализаций). Еще важнее что для понимания нужно только знание основ языка.

Если в CData добавить универсальность
Ни в коем случае, никакому обобщению он не подлежит

Тут как ввсегда всё дело в непродуманной и кривой архитектуре..
Ну облаять велосипедиста - это святое. Я ж учил, вникал, а он.. на коленке чего-то там сбацал! Выходит я зря учил Непонимающий Та не может такого быть!!  Улыбающийся

Ладно, поговорим об архитектуре. Всегда считал (и считаю) что любой "вариант" - зло, и чем меньше он используется - тем лучше. Но увы, иногда это неизбежно, подробный пример я приводил выше - без варианта я не смогу "замкнуть" темплейты. В связи с этим возникает необходимость работать с вариантом как с единым целым. Иначе всякий раз разбираться "а что там сидит" станет невыносимым. Общие методы чем-то напоминают фабрику, но гораздо примитивнее. Напр мне нужны операторы [] и арифметики.

Так что же не так в моей архитектуре? Что же я "неправильно понимаю"? А может это Вы не улавливаете что "архитектура" и "реализация" - совершенно разные термины/понятия? Поэтому дальше будем говорить о реализации, и не употребляйте слов значение которых Вам неизвестно.

Вы арифметические операторы для координат и цвета засунули в CData. Если понадобится что-то сделать с координатой или цветом, которые есть отдельно, не в CData, Вы код (а главное логику операторов) будете дублировать или как?
Да, буду, напр у меня есть методы tan, atan, atan2 и др.

Что мешает написать  нормальные классы координат и цвета, определить для них операции и использовать их в variant, раз уж вляпались в него? Вопрос слегка риторический, можно не отвечать Улыбающийся.
Судя по Вашему приаттаченному коду - Вы прекрасно понимаете "что мешает" Улыбающийся.  Разумеется проскочить великом удается за счет повсемеcтного использования GetNth/SetNh, что, хотя и приемлемо, но не совсем хорошо (3 или 4 "мапирования" вместо одного). Попробуем мапировать напр тот же CData::оператор + (полагаем что операторы для частных случаев имеются)
Код
C++ (Qt)
CData operator + ( const CData & a, const CData & b )
{
 assert(a.m_type == b.m_type && !a.IsNull());  // видимо это надо вынести в метод
 switch (a.m_type) {
   case CData ::type_Value:
     return a.m_value + b.m_value;
 
   case CData ::type_Coord:
     return a.m_coord + b.m_coord;
 
   case CData ::type_Color:
     return a.m_color + b.m_color;
 }
 assert(0);
 return CData();
}
 
И велик быстро теряет прелесть Плачущий Это ж придется каждый оператор так оборачивать. Смысл всей этой возни с визитерами как раз в том что можно схлопнуть этот свитч вызовом темплейта, а здесь (насколько я понимаю) такой возможности нет. Поэтому здесь уже на десятке операторов визитер хорошо выиграет в объеме кода (хотя и не в скорости).

Однако использование визитера - удовольствие сомнительное. Ведь оборачивать каждый оператор все равно придется. А пока сообразишь что к чему приклеить.. Это сейчас задача "на слуху", а ведь часто приходится открывать чужой код без понятия что он делает. Что нам удастся почерпнуть напр их этого?
Код
C++ (Qt)
inline
Coord operator+(const Coord& a, const Coord& b)
{ return Coord{Internal::addArray(a, b)}; }
 
inline
Color operator+(const Color& a, const Color& b)
{ return Color{Internal::addArray(a, b)}; }
 
template <class E>
inline
VarData operator+(const VarData& a, const E& b)
{ return std::get<E>(a) + b; }
 
template <class E>
inline
VarData operator+(const E& a, const VarData& b)
{ return b + a; }
 
inline
VarData operator+(const VarData& a, const VarData& b)
{ return std::visit([&](const auto& b_v) { return VarData{a + b_v}; }, b); }
 
Ептель, 4 обертки для оператора +. Я понимаю что Вы хотели раскатать прием "тип от себя" (не помню как он называется), но все-таки народный свитч здесь получше  Улыбающийся А то объем обертки явно превышает содержание. Неудивительно что до др операторов дело просто не дошло.
« Последнее редактирование: Май 08, 2018, 10:17 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #35 : Май 08, 2018, 10:24 »

Так что же не так в моей архитектуре? Что же я "неправильно понимаю"?
Вы пытаетесь в угоду GUI создавать абсолютно дикие и не эффективные структуры данных и работать с ними, затачивая всю бизнес-логику под эти структуры.
Хотя нужно делать ровно наоборот. Нужно придумывать структуры данных, с которыми удобно решать задачи, и подстраивать GUI под их отображение. Улыбающийся
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #36 : Май 08, 2018, 10:42 »

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

То, что Вы не можете что-то сделать, не означает, что это в принципе невозможно Улыбающийся.

Ептель, 4 обертки для оператора +. Я понимаю что Вы хотели раскатать прием "тип от себя" (не помню как он называется), но все-таки народный свитч здесь получше  Улыбающийся А то объем обертки явно превышает содержание. Неудивительно что до др операторов дело просто не дошло.

Как говорится, наше дело предложить варианты решения задачи, Ваше - отказаться. И писать код дальше в своём стиле Улыбающийся.
Записан

Пока сам не сделаешь...
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #37 : Май 08, 2018, 20:36 »

Цитировать
А может это Вы не улавливаете что "архитектура" и "реализация" - совершенно разные термины/понятия?
Да нет, я улавливаю концептуальные различия между этими понятиями) Знаете, самому приходится писать (правда, справедливости ради, нужно признать, что мои проектики в основном не долгоиграющие: написал, опубликовался и забыл).. Но я всегда стараюсь писать код, макимально расширяемым с перспективой на будущее) Вот, кстатии, на днях пришлось расширять старый проект для Phys. Rev B.) И, как уже отмечал товарищь Old - бизнес логика и взаимодействие с пользователем должны минимально знать друг о друге.. Если вообще должны.. А Вы клепаете по линейной схеме, так сказать, по пути наименьшего сопротивления, не думая о последствиях.. Ну так, во всяком случае, мне видется (имея в виду опыт Ваших постов).

Цитировать
Да, буду, напр у меня есть методы tan, atan, atan2 и др.
И как Вы собираетесь применять эти и другие функции к таким объектам, как Coord и Color? Это нормально вообще?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #38 : Май 10, 2018, 17:51 »

бизнес логика и взаимодействие с пользователем должны минимально знать друг о друге.. Если вообще должны.. А Вы клепаете по линейной схеме,
Этот термин "бизнес-логика" сам по себе идиотский. Нормально сказать напр так:

- есть базовые, фундаментальные структуры данных. Вот они не должны ничего знать об UI, ни одна бубочка, ни один UI-шный хедер проникнуть не должны. Однако обратное совершенно неверно, UI может знать хоть все на свете о базовых данных. Напр строка таблицы имеет доступ к контейнеру + "номер компоненты" (то что подается в Get/SetNth) чтобы отображать/редактировать значения. Это совершенно нормально и никакие принципы не нарушает.

И как Вы собираетесь применять эти и другие функции к таким объектам, как Coord и Color? Это нормально вообще?
Конечно, напр (псевдокод)
Код
C++ (Qt)
CData curr = containter.GetKeyData(index);  
CData next = containter.GetKeyData(index + 1);  
double deltaT =  containter.GetKeyTime(index + 1) - containter.GetKeyTime(index);      
container.SetSplineParam(index, SPLINE_OUT_ANGLE, (next - curr).atan2(deltaT));
Попробуйте тут влезть в разборки с конкретными типами - мало не покажется. Разумеется всегда будет что-то специфичное для каждого типа - ну так сделать все-все общим/колхозным я и не помышлял.

Как говорится, наше дело предложить варианты решения задачи, Ваше - отказаться. И писать код дальше в своём стиле Улыбающийся.
Ну по меньшей мере  мне стало ясно что штатное средство здесь - все-таки визитер, который вовсе не тормознутый (как я полагал). Уже результат. С обертками конечно все равно геморрой, ну "c'est la vie"
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #39 : Май 10, 2018, 18:19 »

Цитировать
Нормально сказать напр так:

- есть базовые, фундаментальные структуры данных. Вот они не должны ничего знать об UI, ни одна бубочка, ни один UI-шный хедер проникнуть не должны. Однако обратное совершенно неверно, UI может знать хоть все на свете о базовых данных. Напр строка таблицы имеет доступ к контейнеру + "номер компоненты" (то что подается в Get/SetNth) чтобы отображать/редактировать значения. Это совершенно нормально и никакие принципы не нарушает.
Нет, бизнес-логика это не только фундаментальные структуры данных - это ещё и их взаимодействие, их интерплей в контексте решаемой проблемы. И определение этих сущностей, которые описывают задачу и то как они должны между собой взаимодействовать, чтоб эффективно её решать и обусловлено бизнес-логикой. А сам процесс наз. проектированием)

Да, гуй взаимодействует с нашими "базовыми классами" посредством предоставляемым ими интерфейса. Но Гуй не должен диктовать, как эти структуры данных должны взаимодействовать между собой.
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #40 : Май 11, 2018, 07:08 »

это ещё и их взаимодействие, их интерплей в контексте решаемой проблемы.
Зачем вы написали столько новых "идиотских терминов". Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #41 : Май 13, 2018, 09:53 »

Нет, бизнес-логика это не только ...
"..ценный мех, но и три - четыре килограмма.." и.т.д.  Данная тема не имеет никакого отношения ни к "бизнес-логике", ни к архитектуре вообще. Ну вот совершенно никакого Улыбающийся  Как мы это делаем (хоть юнионом, хоть визитером, хоть как) - это чисто "реализация", с точки зрения "архитектуры" ничего не меняется - решаемая задача та же самая, мы хотим иметь общие методы для варианта в котором могут сидеть разные классы.

Также удивляет почему фаны темплейтов скептически относятся к совершенно очевидному, напрашивающемся обобщению. Стоило чуть замаскировать конкретикой (число, координата, цвет) - и это уже "кривая архитектура", мол, складывать координату с цветом - бессмыслица. Ну так мешать водку с портвейном никто и не собирался, главное - все они вектора, для них общего кода масса, а наследование не подходит. Конечно махровый темплейт, другого здесь нет.

Ну а UI - не UI - вообще не в тему. Нужен (удобный) доступ к данным, а где он будет использоваться - да где угодно (включая то же UI) 
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #42 : Май 13, 2018, 13:06 »

Также удивляет почему фаны темплейтов скептически относятся к совершенно очевидному, напрашивающемся обобщению.

Смешать всё в кучу - не значит обобщить Улыбающийся. В CData я вижу не обобщение, а жёсткие ограничения. В конечном итоге всё гвоздями прибито к double. Например, можете показать, как будет выглядеть CData с оператором[], если цвет будет представлен в целочисленном формате? Или цвет пришлось во float загнать в угоду этой "реализации"? Заказчик хотел цвет именно во float, и никакие другие форматы ему не нужны?
Записан

Пока сам не сделаешь...
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #43 : Май 13, 2018, 15:50 »

Данная тема не имеет никакого отношения ни к "бизнес-логике", ни к архитектуре вообще.
Имеет и самое прямое.
Нет совершенно никакой необходимости в таких универсальных коллекциях, которые могут хранить числа, координаты и цвета.
Это совершенно разные типы и операции, которые к ним можно применять - разные.
Тут нужно не придумывать универсальный тип для объединения числа/координаты/цвета со странными операциями, а нормально продумать операции для каждого класса, и алгоритмы для коллекций таких типов (многие из них могут быть шаблонными).

А уж когда дойдет то визуализации таких коллекций в UI, то делать свои модели для каждой коллекции типа.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #44 : Май 13, 2018, 17:05 »

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

Ну вот, вы ещё больше "идиотских терминов" понаписали Улыбающийся. Это всё из Букваря слова, в котором ересь одна. Слишком много "типов/коллекций/шаблонов"... Боливар не вынесет столько Улыбающийся. Можно же к Double Единому всё свести и дело в шляпе.
Записан

Пока сам не сделаешь...
Страниц: 1 2 [3] 4 5 6   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.148 секунд. Запросов: 23.