1. Python / Говнокод #12691

    −111

    1. 1
    def add_product_to_user(user, product_id,start_date=None, period=None, limit=True,end_date=None,rate=None,downrate=True):

    Шло время, система обрастала новыми фичами и необязательными параметрами.

    Запостил: хуита, 05 Марта 2013

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

    • А говно в чем? В заказчике, разработчике или опционалах?
      Ответить
    • Опциональные именованные параметры тем и хороши, что их можно смело много.
      Ответить
      • Несмотря на моё отношение к крестам Страуструп хорошо описал почему они отказались от именованных параметров.
        Причина именно в этом: приучает людей передавать по всей системе 20 именованных параметров вместо того чтобы думать головой и заводить структуры (классы, кортежи, мапы, итд).
        Тут же полезно вспомнить фпхацкил, где кол-во аргументов сводят к абсолютному минимуму.
        Ответить
        • Не соглашусь - в конструкторах именованные параметры очень-очень полезны. Вот например, в .NET, чтобы создать Process, заведен специальный класс ProcessStartInfo. Ну вот нахрена плодить сущности? Таких примеров множество.

          Ясно, что в статических языках могут быть проблемы перекомпиляции (насколько я могу судить, опциональные параметры суть baked-in в callsite'е), но в динамических языках типа Питона это совершенно нормально, я считаю, т.к. основная причина использовать структуры вместо аргументов - борьба с собственным инструментом в лице компилятора/линкера/whatever (с другой стороны, в статич. языках это всё равно пол-решения: ну вот был у тебя конструктор с 3 параметрами. Внезапно нужно ещё 3 параметра. Что делать? Заводить специальную структуру? А ведь другой код надеется на конструктор без структуры. Может быть, вообще все методы и конструкторы должны принимать один аргумент в виде структуры изанчально? _А мало ли_? И т.д. И вот уже у нас не код, а over-engenieered говнокод-простыня)

          Per se в принципе хорошая вещь.

          >кортежи
          Семантически набор аргументов в функцию и есть кортеж. А питоновский tuple и вовсе, IIRC, неименованный и позиционный, что есть источник большего числа багов.

          >приучает людей ... вместо того чтобы думать головой
          Если человек не может думать головой -- никто его ни к чему не приучит. Доказательство сему сей сайт.
          Ответить
          • >Например, в .NET, чтобы создать Process, заведен специальный класс ProcessStartInfo. Ну вот нахрена плодить сущности?

            Полагаю парни из мса опытней нас с тобой будут. Всё правильно сделали.
            Плюс сказывается убогость языка и отсутствие оператора with.

            >Семантически набор аргументов в функцию и есть кортеж.
            Правда с одним отличием.

            >ну вот был у тебя конструктор с 3 параметрами.
            Он уже плохо пах.
            >Внезапно нужно ещё 3 параметра. Что делать? Заводить специальную структуру?
            А потом по всей системе горы параметров, имена которые прибиты гвоздями к точке вызова.
            >Заводить специальную структуру?
            Она уже должна быть заведена. Добавить их туда.

            >А ведь другой код надеется на конструктор без структуры.
            Причем тут другой код?
            Ответить
            • >Всё правильно сделали
              Да ничё не правильно, они тупо вдохновилисб WinAPI-структурой STARTUPINFO. А WinAPI это Си, где именованных аргументов не вставишь.

              >Плюс сказывается убогость языка
              Какая такая убогость? Как иначе можно сделать в других языках?

              >А потом по всей системе горы параметров, имена которые прибиты гвоздями к точке вызова.
              А я про чё и говорил? Это плохо только в статич. языках, где ты борешься с собственным компилятором, а в динамич. вроде Питона это совсем не проблема, т.к. ничто нигде не прибито.
              Ответить
              • >Может быть, вообще все методы и конструкторы должны принимать один аргумент в виде структуры изанчально?

                В идеале, да.
                В языках (тот же питон) с сахаром obj.b(other), который значит Object::b(obj,other) можно обойтись и одним. Частичное применение может несколько снижать производительность, потому 3 - оптимально, чтоб строить пары и тройки.

                >а в динамич. вроде Питона это совсем не проблема
                Чую когда-нибудь найдутся люди готовые заменить интерпретатор компиляцией. А без этого питон, при всей своей привлекательности - тормозное г.
                Ответить
              • >Как иначе можно сделать в других языках?
                Да как угодно... Инициализаторы класса, with.
                Просто стоит иногда выглядывать за пределы уютного шарпомирка.
                {
                   workPath ='/bin';
                   windowState=MINIMIZEDF;
                   prioirty = HIGH;
                }
                Ответить
                • Это установка свойств? Если да, то шарп так умеет: new Class() { Property1 = "A", PropertyB = "B" } Но всё-таки "установка рандомных свойств" и "конструктор" как single point of construction -- разные вещи. Если например вдруг какая-то ошибка, то в одном месте, в одном конструкторе, можно более разумным способом разрулить ситуацию, нежели если логика размазана по setter'ам, тем более что ещё setter'ам придётся иметь верификацию на два случая: на случай достроенного объекта и на случай недостроенного объекта. Бр-р-р.

                  Или я не понял, что ты пытаешься втереть.
                  Ответить
                  • >то шарп так умеет: new Class() { Property1 = "A", PropertyB = "B" }
                    >>Инициализаторы класса. (FYI: так оно называется)

                    А вот дополнить свойствами после его создания он не умеет.
                    Ответить
                • > Просто стоит иногда выглядывать за пределы уютного шарпомирка.
                  Кошерная сишечка 99 тоже умеет в красивую инициализацию структур:
                  foo bar = {
                      .workPath = "/bin",
                      .windowState = MINIMIZEDF,
                      .priority = HIGH
                  };
                  Можно даже опустить часть полей, и они будут заполнены нулями.
                  Ответить
                  • это просто инициализация без какой-либо логики. всё-таки конструкторы и логику тоже подразумевают.
                    Ответить
                    • В си не было конструкторов, нет и быть не может. Твой кеп
                      Более того в том же шарпике/яве конструктор отдельно, а инициализатор отдельно.
                      Ответить
            • >Она уже должна быть заведена
              Кто в трезвом уме и памяти заводить по структуре на каждый метод?
              Ответить
          • > ну вот был у тебя конструктор с 3 параметрами. Внезапно нужно ещё 3 параметра. Что делать?
            Удачи тебе. Бегать по проекту и везде добавлять эти 3 параметра.
            А через год еще 5.

            Гавно этот питон, раз даёт возможность так писать.
            Я б вообще сделал язык с процедурами не больше 3-х аргументов.
            И уровнями вложенности операторных скобок не больше 8.
            И в операторе case запретил больше 30 параметров. Итд.
            Короче, идеи где что ограничить брал бы с данного сайта.
            Ответить
            • >Удачи тебе. Бегать по проекту и везде добавлять эти 3 параметра.
              >Гавно этот питон, раз даёт возможность так писать.
              Зачем бегать добавлять 3 параметра, если они именованные и опциональные. Ты дурак?
              Ответить
              • >Ты дурак?
                Да. Раз трачу на тебя время.

                У тебя есть цепочка. Метод А передает пачку параметров методу Б, который передает часть из них методу C.
                Ты решил дополнить А новыми параметрами. Это неизбежно тянет за собой чтоб А передал дополнительные параметры в Б, а тот в что-то в С.

                Если в А передать структуру, то он передаст ссылку на неё в Б, а тот в С.
                Код менять не надо. Только структуру.
                Ответить
                • >Ты решил дополнить А новыми параметрами. Это неизбежно тянет за собой чтоб А передал дополнительные параметры в Б
                  А какова вероятность того, что А, Б и С принимают структуру одного типа в качестве аргумента? Близко к нулю.

                  Если мы дополняем А новыми параметрами, то мы в той же самой функции дополняем параметр и в Б. А дальше пересыл такого опциональногго аргумента уже как-то маловероятен, мне кажется, если это не конструктор с глубоким constructor chaining вверх по наследованию, но имхо, если нужно так много передавтаь данных вверх по наследованию, то автор точно делает что-то не так. Можно же просто переопределять виртуальные свойства.

                  Это как бы меньше кода, да, чем заводить по новой именнованной структуре на каждый метод

                  Алсо, IIRC Питон умеет трактовать опциаональные параметры как словарь, но я не помню как.
                  Ответить
                  • >А какова вероятность того, что А, Б и С принимают структуру одного типа в качестве аргумента?
                    >Близко к нулю.
                    Нет. Более того класс может реализовывать различные интерфейсы, подходя для A, Б и С.
                    Класс может содержать вложенную структуру, которая пойдет в Б, а из него в С.
                    > уже как-то маловероятен
                    Это не аргумент. Потому что в реальности всё строго наоборот.

                    >вверх по наследованию, но имхо, если нужно так много передавтаь данных вверх по наследованию
                    Ну ты же сам предлагаешь передавать в конструктор 100500 параметров. Вот и пойдет оно у тебя по наследованию.

                    Есть 2 способа композиции: наследование и обёртка (адаптер, декорация, итд).

                    В наследовании арументы идут по цепочке вверх.
                    В обертках и адаптерах цепочка из методов.
                    Ответить
                    • >Нет. Более того класс может реализовывать различные интерфейсы, подходя для A, Б и С.
                      Ну это уже скорее философский вопрос "что есть один объект, а что есть два". Ясно что никто в здравом уме не будет передавать целый семантический объект в виде разбросанных по аргументам значений. С другой стороны вот например, есть у нас метод c именованными аргументами String.Compare(String str, int offset = 0, int count = -1, CultureInfo info = null).

                      Во многих случаях надо сравнивать всю строку (offset = 0, count = -1), в других случаях CultureInfo дефолтный. Довольно удобно определять только то, что нужно, через именованные аргументы. Неужели ты предлагаешь здесь создать сущность StringCompareArg? Ну нахуй.

                      >Ну ты же сам предлагаешь передавать в конструктор 100500 параметров. Вот и пойдет оно у тебя по наследованию.
                      А приватными для сего класса данные ну никак не могут быть да?
                      Ответить
                      • >Неужели ты предлагаешь здесь создать сущность StringCompareArg?
                        Да ещё и, блядь, какие-то интерфейсы сверху налепить. Может ещё через фабрику возвращать, да адаптеров сверху намутить?

                        Ебать.
                        Ответить
                        • >здесь создать сущность StringCompareArg?
                          Я в данном месте считаю это излишеством, но во многих толковых либах (гуава) так и поступают.
                          http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Joiner.html
                          Чтобы сделать join (там дохуя всяких аргументов) они порождают специальный объект Joiner где описано как надо джойнить.
                          Потому что можно один раз его породить. И использовать всюду.

                          И это правильно.
                          И пришли они к этому не сразу. А когда всё начало пухнуть и появляться новые фичи.
                          Ответить
                        • Мне трудно объяснить прелесть пресетов и подготовленных заранее настроек.
                          И их преимущество перед передачей куч мусора в методы.
                          Ответить
                      • >А приватными для сего класса данные ну никак не могут быть да?
                        Могут. Но когда наследуешься от конструктора с 20 аргументами их надо как-то передать наверх.
                        Но т.к. они приватные надо либо вызывать в конструкторе пачку сеттеров, либо эту пачку кидать наверх.

                        >есть у нас метод c именованными аргументами String.Compare(String str, int offset = 0, int count = -1, CultureInfo info = null)
                        Редкое исключение, из оперы: попытка написать метод который делает всё.
                        Который к тому же можно заменить регулярками (один аргумент).
                        Ответить
                        • >Но когда наследуешься от конструктора с 20 аргументами их надо как-то передать наверх
                          Смысл опциональных аргументов как раз в том, что они опциональные, т.е. corner-cases, которые не всегда используются. Никто не должен передавать все аргументы. Если у родителя 20 аргументов, значит, он очень сильно genereal purpose, и текущий потомок использует только часть функционала, максимум аргументов 5 на практике. Это твоя проблема, что ты хочешь опциональные аргументы трактовать как неопциональные и таскать по всему коду.

                          >Редкое исключение, из оперы: попытка написать метод который делает всё.
                          Зато код не дублируется десять раз.
                          Ответить
                          • >Зато код не дублируется десять раз.
                            Неправильно.
                            Наоборот. В других таких же all-in-one методах будут встречаться простые куски логики, которые дублируют уже существующие.
                            Ответить
                          • >Если у родителя 20 аргументов, значит, он очень сильно genereal purpose
                            Ну и какой же он общий? Мусорный он. Чем более абстрактный родитель, тем меньше у него должно быть этих полей.

                            >и текущий потомок использует только часть функционала, максимум аргументов 5 на практике.
                            Получается у наследника есть куча пустых полей, логически совсем не нужных ему. Это жутко и плохо.
                            >часть функционала
                            Эту часть можно вынести в отдельную структуру, если она общая. И сделать примесь, например.
                            Таким образом мы тихонько идём к моей концепции минимума аргументов.
                            Ответить
                            • >Получается у наследника есть куча пустых полей, логически совсем не нужных ему
                              Я имел в виду, что потомок реализует часть функционала. Прочий функционал, получается, реализуется родителем по дефолту. Часто встречаемый паттерн специализации.
                              Ответить
                  • >А какова вероятность того, что А, Б и С принимают структуру одного типа в качестве аргумента?
                    >> Метод А передает пачку параметров методу Б, который передает часть из них методу C.

                    Это и будет вложенная структура или реализация интерфейса.

                    >умеет трактовать опциаональные параметры как словарь,
                    >>заводить структуры (классы, кортежи, мапы, итд).
                    Вернулись к тому об чем я говорил. В питоне, по-моему, всё мапы и словари.
                    Просто сахара всякого больше чем в минималистичном js.
                    И продуманная стандартная либа. А так ничего особенного.
                    Ответить
            • >И в операторе case запретил больше 30 параметров
              Да, и потом мы пишем транслятор чего-нибудь во что-нибудь с 31 элементом (напр., ISO-стандарт некоего байткода во внутреннюю оптимизированную IR-форму) и бамс... "Syntax error: 3.14159265 ne razreshil"
              Ответить
              • Да! Везде есть ограничения. Абсолютно везде.
                В том же твоём сраном .NET, та же сраная сдудия не даёт.
                И так детектятся клинические поциенты, которые с горелой жопой прибегают сюда жаловаться.
                http://govnokod.ru/4260#comment47844
                http://govnokod.ru/8627#comment122032



                >Да, и потом мы пишем транслятор чего-нибудь во что-нибудь с 31 элементом
                > "Syntax error: 3.14159265 ne razreshil"
                Именно. И люди мне будут благодарны, что я мудаков криворуких отсеял на этапе компиляции.
                Ответить
                • >В том же твоём сраном .NET
                  Я .NET привёл в качестве примера один раз, хватит пиздеть.

                  Первая ссылка -- про вложенные if'ы. Это совсем не в кассу, так как switch-statement как раз разработан для эффективной обработки большого range'а входных данных, а 128 уровней вложенных if'ов это ограничение вследствие, видимо, плохо написанного парсера, надеющегося на рекурсию и пытающегося избежать stack overflow (та же история с с ограничением на количество вложенных меню в user32)

                  Вторая ссылка тоже говорит про "128 вложенных свичей ". Это опять мимо кассы. Причём тут количество case'ов в одном switch'e?

                  И 30 это слишком мало, я ещё понимаю хотя бы те же 128, ясно что бесконечности нигде не может быть.
                  Ответить
                  • >>>вложенных if'ов это ограничение вследствие, видимо, плохо написанного парсера, надеющегося на рекурсию и пытающегося избежать stack overflow
                    Лооол.

                    Ну-ка покажи мне практический код где было такое необходимо и у тебя реально используется более 128 ifов, или case.
                    Можно отдельным тредом.

                    >switch-statement как раз разработан для эффективной обработки большого range'а входных данных
                    А вот недавно же было.
                    http://govnokod.ru/12676
                    Эффектно.
                    Ответить
                    • >http://govnokod.ru/12676
                      Ясно что в таком таком примитивном случае это просто возврат свойства. Но если идёт, например, трансляция, где результат зависит от разного вида комбинаций нескольких decoupled сущностей, то case'а не избежать. В твоём же примере тупо возврат свойства, локального одному объекту.

                      >Ну-ка покажи мне практический код где было такое необходимо и у тебя реально используется

                      https://github.com/mono/mono/blob/master/mono/mini/mini-x86.c#L2481

                      И я не говорил, что 128 это круто. Я говорил, что твои 30 - слишком мало.
                      Ответить
                      • Пиздец...
                        Это же говно концентрированное.
                        Спасибо. Плюс.
                        Ответить
                      • Объясняю. Если сильно надо
                        Большой свитч можно разбить на несколько меньших.
                        30 нормальным людям должно хватать.
                        А выше, может ты не знал, но есть такая вещь как полиморфизм. Я его не особо.
                        Но он эффективнее.
                        С коммандами x86 можно сделать это логически:

                        switch (type){
                        Case x86:
                        ..
                        Case FPU:
                        ..
                        Case SSE:
                        ..
                        Case SSE2:
                        ..
                        Case SSE3:
                        ..
                        Case SSSE3:
                        ..
                        Case SSE4
                        ...
                        Case AVX
                        ...
                        Case FMA
                        ...
                        Case 3DNOW
                        ...
                        }
                        Ответить
                        • У тебя энтерпрайз головного мозга. Ну у нас теперь два уровня индирекции вместо одного, плюс ещё один enum. Что дальше? Я вот не вижу особой разницы между одним большим простым свитчем в нашем случае, со сгруппированными сходными опкодами ближе друг к другу (плюс комментарии) чем какая-то энтерпрайз-хуйня с полиморфизмом, только потому что ты не умеешь комментировать код. И даже при твоей охуенной группировке мы всё равно спокойно можем перейти границу в 30 case'ов. Добавишь третий уровень группировки?

                          В приведённом коде происходит трансляция IR-формы в опкоды целевого процессора. Какой нахуй "case SSE2"? IR-форма это и так абстракция, там нет SSE, потому что это фича Intel-процессоров. Ребята просто и незамысловато транслируют код одинаковым простым методом "по порядку" для разных процессоров, не вводя никакой overengeneered поебты. Он как раз более читаем и логичен для всех платформ, чем твоё ынтырпрайзное желание категоризировать чисто ради самой категоризации.
                          Ответить
                          • > чем какая-то энтерпрайз-хуйня с полиморфизмом
                            Она будет работать быстрее чем огромный свитч и перебор тысячи комманд.

                            >Ребята просто и незамысловато транслируют код одинаковым простым методом "по порядку" для разных процессоров, не вводя никакой overengeneered поебты.
                            >не вводя никакой overengeneered поебты.
                            Да неужели? Такая незамысловатая портянка.


                            >Ну у нас теперь два уровня индирекции вместо одного, плюс ещё один enum.
                            Объясняю тебе олуху что с 30 ветками в свитче жить можно. Для этого надо объединять данные, структурировать их.
                            Привел пример как.

                            >Что дальше?
                            То что у тебя не будет тупого перебора вообще всего. А по типу комманды мы можем попасть на гораздо меньший диапазон комманд.
                            Ответить
                            • >Она будет работать быстрее
                              На 0.01%? Основанная логика генерации JIT-кода заключается в трансляции MSIL в IR, а не в IR => native , который представлен в обсуждаемом коде.

                              >То что у тебя не будет тупого перебора вообще всего.
                              С хуёв ли будет перебор? Если в энуме нет странных дыр, то Си сгенерирует статический jump-table (соотнесение опкода: if(i < MAX) goto jmptbl[i]; У тебя их будет два. Молодец.

                              Если ты имеешь в виду не алгоритмический перебор, а семантической, то опять же, ту же самую "проблему" решает адекватная группировка с небольшими комментариями.

                              >Объясняю тебе олуху что с 30 ветками в свитче жить можно
                              А я тебе объясняю олуху, что x86 FPU это 80 инструкций. Как они влезут в твой предел 30? Ещё одну индирекцию вставишь? И она ускорит моно каким-то образом аж на 0.001%?
                              Ответить
                              • По крайней мере мой код будет разбит на логические куски, которые можно сопровождать.

                                > что x86 FPU это 80 инструкций.
                                И среди них есть подгруппы. Арифметика, переносы, сдвиги, адреса.
                                Ответить
                          • >мы всё равно спокойно можем перейти границу в 30 case'ов. Добавишь третий уровень группировки?
                            Да. Если потребуется. Со своими кучами именованных параметров ты не слышал о таких базовых вещах структура, дерево, список.
                            Поиск по дереву. Вместо тупого перебора.O (log(n)).
                            Ты же совсем ничего не знаешь, но уже считаешь себя умнее чем MS. Умнее чем люди, которые придумывали структуры данных и алгоритмы.

                            Или добавлю полиморфизм. 30 переборов обычно дольше.
                            Ответить
                            • Какие переборы? Ты обкурился? Для линейного enum'а без необъяснимых дыр в перечислении switch это O(1).

                              Нет блядь, давайте создадим 30 классов с 10 адаптерами и 5 фабриками, чтобы алгоритм был куда быстрее, O (log(n))

                              Пиздец ты наркоман.
                              Ответить
                              • >Для линейного enum'а без необъяснимых дыр
                                А он точно у тебя линейный? А точно у тебя всё туда заинлайнится?
                                А когда ifdefы в серединке пишут, или какие команды отсутствуют в данном процессоре?
                                Ответить
                                • Ну у gcc насколько я помню 3 режима генерации свича.

                                  Если веток мало - генерятся тупо if'ы.
                                  Если почти все ветки разные и стоят плотно - генерится один jump table.
                                  Если много одинаковых веток (дырка = много одинаковых дефолтов) то делается двухуровневая хреновина из index table и jump table.

                                  Так что переборов там быть не должно, даже если полно дырок.
                                  Ответить
                                  • >то делается двухуровневая хреновина из index table и jump table.
                                    Ну я примерно такое и предлагал сделать руками, явно.
                                    В структурированом коде легче и удобней разбираться.

                                    Судя по коду, автор - большой любитель свичей. Даже там где они не нужны.
                                    mono_arch_fregname
                                    Ответить
                                    • Да, делать работу компилятора, вводя ненужные сущности там, где можно было бы обойтись одним jumptable'ом -- вот это уровень 3.14159265!
                                      Ответить
                                      • >Да, делать работу компилятора, вводя ненужные сущности

                                        Делать работу по структурированию кода.
                                        Чтоб оно читабельно было. Для людей.
                                        Именно для этого, в первую очередь, нужны мои ограничения.

                                        И правильно @wxvxw сказал. В кои-то веки абсолютно полностью с ним согласен.
                                        Если б представленный код был сгенерирован - я бы еще понял.
                                        Ответить
                                        • >Делать работу по структурированию кода.
                                          Структурирование линейного трансляции? Может ты ещё для суммирования чисел от 1 до N три уровня абстракций введёшь?
                                          Ответить
                                          • Там тупой копипаст. Как тебе объяснить что человек не должен выполнять работу машины?

                                            Оно либо должно быть логически упорядочено (если это делал человек и будет сопровождать человек).
                                            Либо сгенерировано, если это тупой и простой список.
                                            В обоих случаях switch на 200+ ветвей не нужен.
                                            Ответить
                                            • Big switch have less ctrl+c ctrl+v, than many classes.
                                              Ответить
                                            • Какой тупой копипаст? Из-за твоё структурирования придётся ещё больше кода копипастить, для ветвления по типам.

                                              >Либо сгенерировано
                                              Ага и генератор сам будет больше и тольще (и баговее), чем сама результирующая функция. Браво!
                                              Ответить
                                  • Посудите сами:

                                    switch (cinfo->ret.storage) {
                                    case ArgValuetypeInReg:
                                    /* Allocate a local to hold the result, the epilog will copy it to the correct place */
                                        offset += 8;
                                        cfg->ret->opcode = OP_REGOFFSET;
                                        cfg->ret->inst_basereg = X86_EBP;
                                       cfg->ret->inst_offset = - offset;
                                    break;
                                       default:
                                    break;
                                    }

                                    У поциента запущенный свитчизм головного мозга.
                                    Ответить
                                    • явно что это результат изменинй в коде
                                      Ответить
                                • А как ifdef'ы влияют на что-либо? Это же препроцессор. Компилятор о них вообще не в курсе.

                                  >А когда ifdefы в серединке пишут, или какие команды отсутствуют в данном процессоре?
                                  Значения для энумов генерируется автоматом, инкрементально. Если где-то есть ifdef, убирающий элемент перечисления, то компилятор просто переопредилит энум так, чтобы всё было всё равно sequential. Всю идиллию можно сломать, только если вручную написать OP_MYOPCODE = 1, но так никто в здравом уме не делает (если это не перечисление-флаг или не реализация публичного стандарта).

                                  Это как, в стандартах не определено что такое "стек". Это может быть и вообще динамическая аллокация. Конечно можно задаваться вопросмом "а точно аллокация быстрая? а может быть мне лучше в статическую память писать?", но на практике это тупые вопросы.
                                  Ответить
                              • >Big switch have less ctrl+c ctrl+v, than many classes.
                                >Какой тупой копипаст?
                                Объясняю. Вам обоим.

                                Код представляет из себя вот такую портянку:
                                case OP_UNPACK_HIGHPS:
                                x86_sse_alu_ps_reg_reg (code, X86_SSE_UNPCKH, ins->sreg1, ins->sreg2);
                                break;
                                case OP_UNPACK_HIGHPD:
                                x86_sse_alu_pd_reg_reg (code, X86_SSE_UNPCKH, ins->sreg1, ins->sreg2);
                                break;


                                >x86_sse_alu_ps_reg_reg
                                Вынесение логики в методы - это уже оверхед.

                                >than many classes.
                                В сишке нет классов, уёбок. А полиморфизм - это идея. Идея таблицы с указателями на функции. По сути то же что делает свитч.

                                Прикол в том, что полезных данных этот свитч не несёт. Только унылые breakи - это уже оверхед.
                                И при правильной группировке можно задать:
                                вот для этого списка комманд нужно вызвать этот метод, для этого - этот.
                                Тогда от свитча можно избавится вовсе.

                                Кратко. Моя идея заключается в следующем:
                                Задаём массив соотвествия, который содержит полезную информацию и убираем большой свитч.
                                [OP_UNPACK_HIGHPS,X86_SSE_UNPCKH
                                ,OP_UNPACK_HIGHPD,X86_SSE_UNPCKH
                                .....
                                ]

                                Ответить
                          • >Я вот не вижу особой разницы между одним большим простым свитчем в нашем случае, со сгруппированными сходными опкодами ближе друг к другу

                            Он не простой, а с ifdefами. И попытками заточек под конкретную архитектуру и набор комманд.
                            Ответить
                      • А что в этом коде хорошего? Типичная нечитабельная портянка. Возможно, имело бы смысл такое генерировать, но писать вручную? - это ж маразм.
                        Ответить
                        • Что в нём нечитабельного? Код не мой, и он совршенно читаем. Выборка IR-опкода => ответная реакция на него в виде генерации кода некой манипуляции на целевом-процессоре. Названия макросов и функций говорят за себя. Мне кажется, тут совсем не к месту писать стихи.
                          Ответить
                          • Стихи?.. вы о чем? Код - портянка, сталкивался с таким сотни раз. В нормальном читаемом коде функции занимают не больше экрана (да и то уже много, зависит от того, какой экран). Для того, чтобы работать с таким свитчем нужна дополнительная программа, справочник, и неимоверное желание скроллить окно взад-вперед в поисках нужного фрагмента кода. Кроме того, там еще ifdef ifdef'ом погоняет. Я не стал искать, т.как тяжело и влом, но почти наверняка есть ifdef'ы которые дублируются.
                            Такие вещи правильно разбивать на блоки, использовать какой-нибудь жаблон типа посетителя, например, который бы позволил разнести действия связанные с конкретными опкодами в файлы относящиеся к конкретному опкоду / группе опкодов. Хз. почему там свитч существует, возможно кто-то решил сэкономить процессорных такт угробив на этот кусок кода лучшие годы своей жизни. Идеология типичная для Си, когда даже при возможности запилить шаблон / сгенерировать, люди все равно будут врукопашную все оптимизировать, разворачивать циклы, инлайнить вручную и т.п...
                            Ответить
                            • > люди все равно будут врукопашную все оптимизировать, разворачивать циклы, инлайнить вручную и т.п
                              Иногда это действительно нужно ;) Но не так часто.
                              Ответить
                            • Это довольно straightword-трансляция IR-представляения в машинный код. Ну не нужны здесь никакие "паттерны", даже разбивка на подметоды. Ну нахуя? "В нормальном читаемом коде функции занимают не больше экрана" -- правильно, если в коде есть сложная логика, а не просто линейная трансляция, блядь.
                              Ответить
                              • А. Чуть не забыл.
                                В моем языке будут запрещены чрезвычайно длинные процедуры и модули.
                                Обязательно.
                                Ответить
                                • > чрезвычайно длинные процедуры и модули.
                                  Тогда уж и длинные строки.
                                  Ответить
                              • Правильно, код должен соответсвовать задаче: если она прямолинейная, то ее нужно генерировать, а не печатать 100500 раз одно и то же. Повторять один и тот же код много раз подряд - это антитезис хорошего программирования.
                                Но, нужно обратить внимание, что тут не все так просто, есть по дороге какие-то исключения, ветвления и т.п. на которых нужно 1. сконцентрировать внимание читающего (а не похоронить где-то в общей куче), 2. их нужно сгруппировать так, чтобы их было проще найти, в зависимости от возможной поставленной задачи (например, нужно найти все инструкции, которые будут актинвы при каком-то выбранном условии). Шаблон типа посетителя как раз таки и поможет это сделать, т.как вместо того, чтобы листать огромный свитч и искать в нем необходимую инструкцию, можно будет открыть файл в котором она предположительно находится, и максимум с двух-трех попыток угадать - это все равно избавит от необходимости листать весь свитч.
                                Ответить
                                • Да, искать по коду не удобно. Но если такой большой код вывести в отдельный файл, то ctrl+f вполне достаточно.
                                  Ответить

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