1. C++ / Говнокод #3173

    +98

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    template<unsigned AxesQount, class Conten>
    const Vector<AxesQount, Conten> Vector<AxesQount, Conten>::operator-(void) const
    {
        return *this*-1.0;
    };
    
    template<unsigned AxesQount, class Conten>
    const Vector<AxesQount, Conten> Vector<AxesQount, Conten>::operator+(void) const
    {
        return *this;
    };

    Чужой велосипед. Пытался использовать в своём проекте, но передумал.

    Запостил: Говногость, 07 Мая 2010

    Комментарии (71) RSS

    • Да мы уже поняли, что С++ говно.
      Ответить
    • так а в чем проблема. унарные операторы перегружены. operator-() - как бы все в порядке и похоже пользуется перегруженым operator*(Vector). operator+() как бы не нужен, но может там есть чего в operator=(). или просто для полноты добавили.

      я с векторами мало работал. знакомый у меня есть специалист. он говорил что стандартный val_array так обложен оптимизациями (что есть его raison d'etre) что ему около полугода надо было что бы все освоить и в нормальном темпе портировать старый векторный код с фортрана.
      Ответить
      • >>>ему около полугода надо было что бы все освоить
        Вот уж обрадовал! Да за полгода с нуля на асме написать можно. Говно ваш С++, тормозное, непродуктивное говно.
        Ответить
        • от языка это никогда не зависило. я бы сказал что за полгода въехать во всю специфику и начать писать код на уровне/лучше чем десятилетиями вылизаные фортрановские библиотеки, это подвиг.

          с HPC (high performance computing) совместимых языков кот наплакал. Java/C# - гарбадж коллекшн отъедает 5-10% производительности с легкостью. 5-10% производительности от кластера стоящего $$$$$$$$$$ это все равно $$$$$$$$$ - или по-русски говоря - охуеть сколько денег. математические языки тоже есть, но не у всех есть нужные библиотеки и не все настолько портируемы как простые С/С++. ну фортран тоже есть, но хороший, правильно параллелизирующий компилятор стоит $$$$$.
          Ответить
          • Взаимоисключающе звучит: если есть бабло на кластер и нужен хороший результат, то уж лучше и на этот самый компилятор/софт раскошелиться, а не воротить собственные костыли на говнос++ с далеко неочевидным профитом.
            Ответить
            • ну это оно звучит для вас. за железо платят из одного бюджета. за девелопмент софт, который часто лицензируется по головам, платят из другого бюджета. реалии капитализма.

              и профит от порта на С++ тоже как бы почти очевиден: при переходе на другой кластер, нужно только перекомпилировать. С/С++ компиляторы либо бесплатные, либо стоят копейки (или комбинация: девелоперы сидят на GCC, релиз компилится коммерческим компилятором). Фортран нужно другую версию компилятора для другого железа лицензировать по новой.
              Ответить
          • > Java/C# - гарбадж коллекшн отъедает 5-10% производительности с легкостью

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

            пруфы давай, что гц съъедает 5-10%, или пиздабол.
            Ответить
            • пруфов у меня естественно нету. народ в соседнем отделе пробовал оптимизировать их батч джобы на Яве писаные. CPU загрузка 100%, 8 процов (4 дуал кор Итаниума), 8 независимых потоков - все как бы красиво. а если время которое реально сами батчи делались из логов сложить, приходили к тому что работало только около 7.5 процессоров. а остальные пол проца были заняты чем то другим. т.к. ничего другого на системе не работает, I/O крайне мало, кернел тайма почти нету - да и java сама ни разу с 100% CPU загрузки не опускалась, вывод был только один - гарбадж коллекшн. Другого то ничего помимо программы в самой Яве не делается.

              если ты обрабатываешь запросы с сети и никогда до полной CPU загрузки не доходишь, эффекта GC ты никогда и не увидишь: он работает в отдельном потоке и время его испольнения на времени обработки запроса не отражается.

              а вот если до 100% доходишь ... ну мои коллеги уже поимели этот опыт. да как бы это батч джобы. никто там на время сильно не смотрит. наши тест делали только что бы знать насколько долго будет работать и будет ли вообще работать.

              ну а так как я в контексте HPC постил, то понятно что там системы стараются на все 100% грузить. и на весь оверхед смотрят под лупой. кастом кернелы, кастом libc там нормальная практика. 1-2% выиграной производительность иногда значит что расчеты будут делаться несколько часов/дней быстрее - и за каждым процентом они гоняются.

              > также в с++ фрагментируется куча. если долго крутиться, то будет тормозить сильнее языка со сборкой мусора.

              старая проблема которая уже давно не проблема. почти на всех системах которых я работал есть выбор мемори аллокаторов. либо дежурный из либц, либо чего понавороченей для многопоточности/с защитой от дефрагментации/с поддержкой миллиардов мелких блоков. (E.g. Solaris' libumem, HP-UX's mallocng).
              Ответить
              • показать все, что скрыто>пруфов у меня естественно нету.
                Нету пруфов - Идешь нахуй.
                Ответить
                • опыт из работы уже не в счет...

                  ЗЫ начинаю верить что гестов надо давить.
                  Ответить
              • > 7.5 процессоров. а остальные пол проца были заняты чем то другим. т.к. ничего другого на системе не работает, I/O крайне мало, кернел тайма почти нету

                а что насчёт памяти? много ли выделялось? сборщик мусора какбэ просто так не работает, для этого условия нужны. когда памяти нормальное количество он засуспенжен же.

                > с защитой от дефрагментации

                какие алгоритмы? мне кроме прямого компактирования в голову ничо не приходит. а для него нужно иметь полноценный рантайм

                с настройкой гц не баловались? с разными опциями (включить серверный режим, там)?
                Ответить
                • > а что насчёт памяти? много ли выделялось?

                  меня на те тесты звали как юниксода звали, что бы трейсы системы интерпретировать. тест делали ночью, работал где-то 5 часов - но на серваках памяти 64ГБ. тип задачи: маппинг полей входных сообщений по длииииному списку правил.

                  > какие алгоритмы?

                  сложно их даже алгоритмами называть. http://en.wikipedia.org/wiki/Memory_pool - это в принципе стандартная практика для телекоммуникационного софта.

                  хотя у нас и куча тупых С++ модулей которые и libc пользуются - и работают месяцами без проблем.

                  > с настройкой гц не баловались?

                  я строчку как они стартуют Яву наковырять могу. основная проблема в нашем случае что это должно работать не только с Сановской JRE, но так же и IBM'овской на AIX'ах. поэтому сильно на уровне JRE не оптимизуруют - больше сосредотачиваются что бы оно работало с обеими JRE (по граблям портабельности параметров Явы ходят постоянно).
                  Ответить
                • >AxesQount, Conten
                  Это немецкий?
                  Ответить
            • меня на те тесты звали как юниксода звали, что бы трейсы системы интерпретировать. тест делали ночью, работал где-то 5 часов - но на серваках памяти 64ГБ. тип задачи: маппинг полей входных сообщений по длииииному списку правил.
              Ответить
          • > совместимых языков кот наплакал

            У меня слёзы по лапкам потекли...
            Ответить
    • >AxesQount, Conten
      Это немецкий?
      Ответить
    • >*this*-1.0
      Что это значит вообще? this-1?
      Ответить
    • ОЛОЛОЛО
      С++ говнО.
      Кто ещё сомневается?
      Ответить
    • Кончайте уже постить С++. Я уже захожу суда просто, что-бы посмеяться. Для меня он уже на уровне 1С.
      Ответить
    • Перегружать operator+(void) это такой прикол, да?
      Ответить
    • template<unsigned AxesQount, class Conten> const Vector<AxesQount, Conten> Vector<AxesQount, Conten>::operator-(void) const
      Как вообще пользоваться этой херью? Это куча какой-то каши, а внутри кот наплакал:
      return *this*-1.0;
      Это вот что-бы описать один ничего не делающий оператор - нужно написать столько говна?
      Каково здесь соотношение полезного и бесполезного кода? Бесполезного примеро раз в 10ть больше. С таким кодированием проект и к новому году не закончить.
      И вообще все эти операторы в С++ - не оптимальное быстродействие.
      Ответить
    • >не оптимальное быстродействие
      Ыыы. operator+ возвращает результат по значению. Афтар долбоёп. Он тем более потеряет быстродействие, особенно если вектор состоит, например, из пары тысяч значений.
      Ответить
      • С чего бы? Это же унарный плюс, что ты там предлагаешь возвращать по ссылке?
        Ответить
      • оператор константный и не может менять свой объект, поэтому должен вернуть новый...
        единственная говнокодность это то что возвращаемое значение не константа и операция типа
        -vec = other;
        возможна хоть и бессмысленна...

        вот листинг подобной функции для флоата

        _TEXT SEGMENT
        ??$?GM$02@pmath@@YA?BV?$Vector@M$02@0@AB V10@@Z PROC ; pmath::operator-<float,3>, COMDAT
        ; ___$ReturnUdt$ = eax
        ; _v$ = ecx
        ; Line 201
        fld DWORD PTR [ecx]
        fstp DWORD PTR [eax]
        fld DWORD PTR [ecx+4]
        fstp DWORD PTR [eax+4]
        fld DWORD PTR [ecx+8]
        fstp DWORD PTR [eax+8]
        fld DWORD PTR [eax]
        fld DWORD PTR __real@bf800000
        fmul ST(1), ST(0)
        fxch ST(1)
        fstp DWORD PTR [eax]
        fld DWORD PTR [eax+4]
        fmul ST(0), ST(1)
        fstp DWORD PTR [eax+4]
        fmul DWORD PTR [eax+8]
        fstp DWORD PTR [eax+8]
        ; Line 202
        ret 0
        ??$?GM$02@pmath@@YA?BV?$Vector@M$02@0@AB V10@@Z ENDP ; pmath::operator-<float,3>
        ; Function compile flags: /Ogtp
        _TEXT ENDS

        и для инта

        _TEXT SEGMENT
        ??$?GH$02@pmath@@YA?BV?$Vector@H$02@0@AB V10@@Z PROC ; pmath::operator-<int,3>, COMDAT
        ; ___$ReturnUdt$ = eax
        ; _v$ = ecx
        ; Line 201
        mov edx, DWORD PTR [ecx]
        mov DWORD PTR [eax], edx
        mov edx, DWORD PTR [ecx+4]
        mov DWORD PTR [eax+4], edx
        mov ecx, DWORD PTR [ecx+8]
        mov DWORD PTR [eax+8], ecx
        mov edx, DWORD PTR [eax]
        neg edx
        mov DWORD PTR [eax], edx
        mov ecx, DWORD PTR [eax+4]
        neg ecx
        mov DWORD PTR [eax+4], ecx
        mov edx, DWORD PTR [eax+8]
        neg edx
        mov DWORD PTR [eax+8], edx
        ; Line 202
        ret 0
        ??$?GH$02@pmath@@YA?BV?$Vector@H$02@0@AB V10@@Z ENDP ; pmath::operator-<int,3>
        ; Function compile flags: /Ogtp
        _TEXT ENDS
        Ответить
        • Вообще то можно было бы вернуть это и по ссылке.
          template<unsigned AxesQount, class Conten>
          const Vector<AxesQount, Conten>& Vector<AxesQount, Conten>::operator+(void) const
          В чём проблема?
          Ответить
          • с оператором + да... он и не используется.. а с оператором - нельзя...
            так как при
            vec1 = -vec2;
            получим что оба вектора равны... а это неправильно....
            Ответить
            • >он и не используется
              Я бы так не стал утверждать. Всякие извращенцы всёж есть.

              У вас плохая связанность предложений. Потренируйтесь на днях. Может среди программистов есть такие, что не умеют выражать мысли, тк для них разговор происходит слишком быстро, но на форуме есть время подумать и сформулировать свою мысль.
              Ответить
              • ок...
                Ответить
                • Не нужно так обречённо. Я возможно не прав. Может быть у вас сейчас просто не было времени подумать над ответом. :)
                  Ответить
                  • Да-да. С ними надо без жестких выражений общаться - слабенькая психика ведь не выдержит.
                    Ответить
                    • И сильных личностей переодически нужно подбадривать. :)
                      Этот человек, определённо, сильный. Не у каждого хватит смелости согласиться:
                      >ок...
                      Большинство ответит грубым хамством.
                      Ответить
              • Наверно С++ так пагубно действует.
                Ответить
            • Вам, должно быть, будет интересно:
              Запись
              Matrix c = a + b;
              эффективнее, чем
              Matrix c;
              c = a + b;
              Это описано в
              http://valera.asf.ru/cpp/book/c14.shtml
              после строк "14.8. Соображения эффективности A".

              Кто-нибудь это проверял? Много, ли компиляторов, поддерживает эту оптимизацию?
              Ответить
              • По-моему, это очевидно.
                Matrix c = a + b; // Вызывается оператор сложения и копирующий конструктор

                Matrix c; // Конструктор по умолчанию
                c = a + b; // Оператор сложения и оператор присваивания
                Ответить
                • Да нет. Там намекали на другое. Это здесь непричём.
                  Ответить
                  • Вкратце, на что "там намекали" в таком случае ?
                    Ответить
                    • Про передачу параметра по ссылке 3ем параметром во втором случае.

                      Что-бы понять - легче прочитать. Там пару обзацев всего лишь. Всё читать не нужно.
                      Это в разделе: "14.8. Соображения эффективности A".
                      Ответить
                      • Речь об этом "Компилятор в состоянии распознать, что возвращается объект класса и выполнить трансформацию его значения и без явного расширения языка." что ли ?
                        Ответить
              • про оптимизацию можно почитать здесь http://alenacpp.blogspot.com/2008/02/rvo-nrvo.html
                Ответить
            • Ещё в новом стандарте С++0х появились:
              Ссылки на временные объекты/Семантика переноса (Rvalue Reference/Move semantics).
              Это позволяет делать дополнительную более оптимальную перегрузку операторов c передачей параметра по &&. В том числе это позволяет возращать объекты по ссылке, вместо того, что-бы возвращать их по значению. Притом иногда нет необходимости выделять дополнительную память под объект, тк результат может храниться в этом самом временном объекте, который возвращаем по ссылке.
              Ответить
              • Вообщем, код можно писать более оптимально.
                Остаётся дождаться стандарта, когда можно будет совсем избавиться от передачи результата по значению.
                Ответить
            • Ещё один вопрос оптимизации:
              На основание статьи, о том, что для некоторых операций языки с динамическими типами работают быстрее языков со статическими типами (в том числе С++/C#/им подобные):
              http://www.smalltalk.ru/articles/cpp-is-faster.html
              Появилась статья, о применении опыта динамических языков для оптимизации в С++:
              http://www.smalltalk.ru/articles/cpp-pic.html
              Ответить
              • Можно ещё добавить к статье
                http://www.smalltalk.ru/articles/cpp-pic.html
                , что лучше делать так:
                typedef const type_info* TypeId;
                
                template <class Type>
                struct typeIdOfTypeFast
                {
                	static TypeId Get;
                };
                
                template <class Type>
                TypeId typeIdOfTypeFast<Type>::Get=&typeid(Type);

                и использовать это:
                if(typeId()==typeIdOfTypeFast<CA>::Get)

                взамен:
                if( typeId() == &typeid(CA) )

                Это позволит убрать лишний вызов функции (закешировать) typeid(CA), хотя в хороших компиляторах это должна быть константа.
                Ответить
                • > хотя в хороших компиляторах это должна быть константа.

                  это не может быть константа. ходил недавно по граблям "почему RTTI (typeid(), dynamic_cast) под локом глобальным работает" (есть у нас там пара пидапрограммеров которые этим весь код свой обкладывают).

                  так вот расковырял относительно быстро: загрузка/выгрузка динамических библиотек меняет RTTI структуры приложения.
                  Ответить
                  • >это не может быть константа
                    Почему не может?
                    typeid(CA) - получение идентификатора по типу, а идентификатор типа (не переменной) известен на этапе компиляции. Вполне может быть константой.
                    Приведённый выше код выполняет работу компилятора на всякий случай, если тот туп, но думаю в новых компиляторах это не понадобится.
                    Ответить
              • Хотя тру пацанчики делают этот так:
                class P
                {
                public:
                	virtual void a()=0;
                	virtual void b()=0;
                	virtual void c()=0;
                	virtual void d()=0;
                	virtual void e()=0;
                	
                	virtual void VirtualBatchCall()=0;
                };
                
                class C1:public P
                {
                public:
                	virtual void a(){/*...*/};
                	virtual void b(){/*...*/};
                	virtual void c(){/*...*/};
                	virtual void d(){/*...*/};
                	virtual void e(){/*...*/};
                
                	virtual void VirtualBatchCall()
                	{
                		C1::a();
                		C1::b();
                		C1::c();
                		C1::d();
                		C1::e();
                	};
                };
                
                class C2:public P
                {
                public:
                	virtual void a(){/*...*/};
                	virtual void b(){/*...*/};
                	virtual void c(){/*...*/};
                	virtual void d(){/*...*/};
                	virtual void e(){/*...*/};
                
                	virtual void VirtualBatchCall()
                	{
                		C2::a();
                		C2::b();
                		C2::c();
                		C2::d();
                		C2::e();
                	};
                };
                
                //...
                P& t=*new C1;
                t.VirtualBatchCall();
                Ответить
                • Хотя реальные тру пацанчики так просто не делают.
                  Ответить
                • зачем a,b,c,d,... делать виртуальными, если мы к ним обращаемся на прямую?
                  Ответить
                  • Для пущего эффекта, да чаще в реальности нужно же обратиться и к отдельной функции, например t.b();
                    Ответить
        • Что за этот у вас компилятор? Кажется не Некрософт.
          Ответить
    • Ebantvere picrelated.
      Ответить
    • в просторах интернетов нашёл годный объект троллинга для ненависников С++ : http://alenacpp.blogspot.com/
      :-)
      Ответить
    • - Убирайся, - выдавил Руслан из себя сквозь зубы.
      Ответить

    Добавить комментарий