1. Java / Говнокод #6946

    +85

    1. 1
    String methodName = (new Exception()).getStackTrace()[1].getMethodName();

    Вот как надо получать имя метода. Это вам не __func__ ...

    Запостил: roman-kashitsyn, 14 Июня 2011

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

    • А как надо? Thread.currentThread().getStackTrace()[0].getMethodName()?
      Ответить
      • Именно так. Неплохо бы ещё код почитабельнее сделать.
        Ответить
      • Только Thread.currentThread().getStackTrace()[2].getMethodName(). И хотя это выглядит на чей-то взгляд предпочтительнее, на самом деле Thread.currentThread().getStackTrace() внутри зовёт (new Exception()).getStackTrace().
        Ответить
    • .
      Ответить
    • Не говнокод.
      Ответить
    • > Это вам не __func__
      и отродясь такого не было
      Ответить
      • Это типа тонкий намёк на то, как эта операция делается в ANSI C.
        Ответить
        • можно устроить срач, на тему "какой подход лучше"
          Ответить
          • __func__ много быстрее Thread.currentThread().getStackTrace()[0].getMethodName()
            Ответить
            • [CO]
              А С вообще намного быстрее чем Java.
              [/CO]
              Ответить
              • Если на Си будет писать жопорукий пидорас, то джава обгонит щи++ в 2 счёта.
                Ответить
                • если Java будет выполняться на Tianhe-1A, а си на калькуляторе, то тем более.
                  p.s. а вообще не равноценные сравнения, посадите жопорукого тоже на джабу тогда.
                  Ответить
                • Если на жигуль поставить более мощный двигатель, а ферари будет ехать в противоположную строну, то жигуль обгонит ферари в 2 счета.

                  К тому же Ваш пост обижает пидорасов.
                  Ответить
                  • >Ваш пост обижает пидорасов.
                    Однажды, давным давно, говнокод сошелся во мнении, что на крестах пишут только пидорасы.
                    Не поминайте лихом. C††, аминь.
                    Ответить
                    • > Однажды, давным давно, говнокод сошелся во мнении, что на крестах пишут только пидорасы.
                      признавая это утверждение, всем пришлось признать, что они пидоры со стажем.
                      Ответить
                    • >на крестах пишут только пидорасы.
                      И где здесь кресты, LinuxGovno ?
                      Вроде как мы говорили о Си.

                      алсо самофикс
                      >то жигуль обгонит ламборджини в 2 счета.
                      Ответить
                  • >Если на Си будет писать жопорукий пидорас, то джава обгонит Cи в 2 счёта.
                    >Ваш пост обижает пидорасов.
                    Неужели пидорасы считают, что на сях писать западло и обидно?
                    Ответить
              • > намного быстрее
                зря вы так. Это уже давно не так. Где-то кто-то даже замеры проводил... Конечно, интерпретируемый код никогда не станет быстрее нативного, но скорости уже сравнимы.
                З.Ы. Если раньше разница была х100 раз, то сейчас где-то х1.1
                похоже Java-процессоров ждать уже приходится
                Ответить
                • >Где-то кто-то даже замеры проводил...
                  ага.

                  inb4 prooflinks paste from lm

                  В холиварах жабакодеры любят приводить в качестве главного аргумента того, что жаба не тормозит, линки на бенчмарки, в которых сравнивается скорость нативного кода и жабо-байткода. Обычно заголовки таких тестов выглядят в духе «Жаба обгоняет по производительности С++» и приводится код, где Java быстрее C/C++ (нужное подчеркнуть). Это происходит по нескольким причинам:

                  1. Такие бенчмарки примитивны: они работают только со скалярными типами (с такими, как int, double), память под которые выделяется на стеке, используются простые операции и, наконец, весь код находится только в одном классе.
                  2. Компилятор Java уверен, что программист - дебил, поэтому за программиста производит улучшения кода на этапе компиляции. Так например что-то вроде int c = 1000; for (int i = 0; i < 100000; i++) { c++; ... } будет приведено к чему-то вроде inc c; for (c = 1000; c < 101000; c++) { ... }, в то время как компилятор C уверен что программист знает что делает, и добросовестно скомпилирует самый дебильный код.
                  3. Обычно такие тесты содержат много циклов, а замеры проводятся не во время первого запуска, а когда JIT-компилятор уже отработал. Значит, меряется скорость хорошо оптимизированного динамически скомпилированного кода. Да и garbage collector не успевает в таких программах отработать.
                  4. Авторы бенчмарков зачастую поверхностно знают C/C++ и используют его в «жабьем» стиле, например используя кучу там, где она не нужна (и ноют про необходимость free и delete).
                  Ответить
                  • Насчёт п.2 — неправда, компиляторы C и С++ достаточно умны, чтобы вытворять и не такие вещи (именно благодаря этому на «переносимом ассемблере» можно писать более-менее высокоуровневый код).

                    Насчёт остального — тремя руками за (особенно п.4).
                    Ответить
                    • третий пункт ой как справедлив также и для апологетов .NOT
                      Ответить
                      • Ну да, если проводить замеры на нескольких итерациях и выводить отдельно, это ох как заметно.
                        Ответить
                  • > и используют его в «жабьем» стиле
                    а заодно и по всем пунктам. Уж если сравнивать быстродействие, то код бенчмарков должен быть эквивалентен.

                    Так что текст необъективен, явно прослеживается тенденция укусить жабакодеров, на голом месте обвиняя их в читерстве и подсиживании (мол, используются скрытые оптимизации, а код на С++ нарочито крив), при этом используется подмена понятий
                    > например используя кучу там, где она не нужна

                    ладно, даже, по пунктам:
                    1. "работают только со скалярными типами". Отлично, прямо вижу, как охота обогнать на повороте, поскольку в С\С++ строки- это последовательность байтов, тогда как в жабке - это объекты
                    "спользуются простые операции и, наконец, весь код находится только в одном классе" - бенчмарк должен быть простым, нет? сложный бенчмарк быстро бы наполнился говнокодом, в котором трудно уследить "обгон на поворотах"

                    2. Все современные компиляторы стараются оптимизировать код по мере их интеллекта

                    3. "Обычно такие тесты содержат много циклов" - а без циклов будете наносекунды сравнивать? Подмена понятий
                    "а когда JIT-компилятор уже отработал. Значит, меряется скорость хорошо оптимизированного динамически скомпилированного кода". Опять подмена понятий. То есть, жаба должна код постоянно "компилировать" подобно "чистому" интерпретатору? Позвольте, но тут же явно получит преимущество уже скомпилированный код.
                    "Да и garbage collector не успевает в таких программах отработать" - пардон, но в С++ его вообще нет! Хорошо, можно есть вызывать System.gc(), но надо учитывать при этом, что он уберет не созданный объект, а вхолостую будет пересматривать "где тут еще грязь?", что, конечно, сразу снизит скорость.
                    Ответить
                    • >в С\С++ строки- это последовательность байтов, тогда как в жабке - это объекты
                      std::string не пробовали? Объекты в С++ между прочим, ага.
                      Ответить
                  • -
                    Да, мне обидно за топики "Жаба обгоняет по производительности С++", где, конечно, нечестная игра ведется уже с противоположной стороны. Но я и не берусь заявлять подобное.
                    Я всего лишь хочу искоренить древний миф "Жаба - это такое толстое и ужасно неповоротливое существо, на котором только хелловорлды писать, а программа посложнее надежно повесит даже суперкопьютер".
                    Вернемся на исходные мои "Конечно, интерпретируемый код никогда не станет быстрее нативного, но скорости уже сравнимы. З.Ы. Если раньше разница была х100 раз, то сейчас где-то х1.1"
                    Ответить
                    • >"Да и garbage collector не успевает в таких программах отработать" - пардон, но в С++ его вообще нет!

                      в С/C++ очистка производится вручную free/delete и на это также уходит время.
                      Если в яве рано или поздно не вызывать gc - она просто засрет все.

                      >сложный бенчмарк быстро бы наполнился говнокодом
                      правильно нужно писать такие бенчи
                      for (i=0; i<100500;i++) sum+=sin(i);
                      которые совершенно не отражают реалий.

                      >сейчас где-то х1.1
                      вот свежий и более менее объективный бенч от гугла
                      https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf
                      Ответить
                      • > в С/C++ очистка производится вручную free/delete и на это также уходит время.
                        удалить один обьект сразу быстрее, чем пробуждать целый поток с его хз какими сложными алгоритмами (который к тому же может решить, что сейчас делать он ничего не будет, а оставит на потом = ) )

                        > Если в яве рано или поздно не вызывать gc - она просто засрет все.
                        два момента:
                        1. System.gc() не обязателен, это только тормошение сборщика, а то сам он хз когда решит поработать
                        2. если delete безусловно удалит объект (правильно это или нет), то сборщик может отказаться удалять, и тот будет висеть в памяти даже до завершения JVM, поэтому кажется, что жаба жрет память.
                        А на самом деле это,наверное,самая распространенная ошибка даже неглупых жабакодеров, т.к. что бы объект был собираемым, нужно не только зануллить ссылку на него, но и отцепить от других объектов (например, разрегистрировать слушателей).
                        И это не всегда тривиальная задача, отследить и удалить все связи (например, классы ссылаются на загрузившие их класслоадеры, которые тоже надо удалять)

                        > которые совершенно не отражают реалий.
                        бенчи на то и бенчи, что бы быть бесполезными в других аспектах. Тогда уж брать сложные реальные приложения в качестве бенчей... Ну сами понимаете, смешно.... = )
                        Ответить
                      • а ссылка интересная... 45х все-таки получается
                        Ответить
                      • > Если в яве рано или поздно не вызывать gc - она просто засрет все.
                        Когда-то давно обсуждался сборщик JVM и пришли к выводу, что он гарантированно сработает при попытке распределить на куче больше байт, чем в данный момент помечено свободными, т.е. в один прекрасный миг накладные расходы распределения будут суммированы с неявным освобождением.
                        Ответить
                      • >Если в яве рано или поздно не вызывать gc - она просто засрет все.

                        Ну это верно только для ранних горе-оптимизаторов. Т.е. чувак видит, что в его хелловорлде жабка использует 100 мб -- цокает языком, что за ужас, говорит. Только он забывает, что жабка это намеренно делает и с запасом, т.к. видит, что в системе 99% времени оперативка и так простаивает с незанятыми ~60-70%.

                        Т.е. человек заботится о оперативной памяти, которую он нифига не юзает.

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

                        Смешные эти, горе-оптимизаторы, право.
                        Ответить
                    • Фактически, что-бы было все честно - нужно в С++ не использовать кучу (только стек), тк в джаве есть гц коллектор, который все потом удалит уже после выполнения представленного теста и вывода его результатов, в то время как С++ будет выделять и освобождать в реальном времени ещё во время выполнения тестов.

                      Тоесть, если программист С++ уг и все выделяет в куче, то какой смысл в сравнении производительности, языковые возможности С++ не использовались на максимум. Это уже бы получилось измерение человеческого фактора, а не сравнения производительности.
                      Ответить
                    • А вообще перегрузить оператор new в С++ на пулы или подключить библиотеку fastHeap (тоже на пулах) и gc явы будет порван, как "тузик грелкой".

                      Можно будет смело юзать кучу в тестах на обоих языках, если хочется честности.
                      Ответить
                  • > Компилятор Java уверен, что программист - дебил, поэтому за программиста производит улучшения кода на этапе компиляции

                    это полное враньё, в Java компилятор (javac) известен тем, что вообще почти ничё не оптимизирует. это сделано специально, чтобы больше было пространства для оптимизации джиттером. алсо он так говорит как будто с++ ничего не оптимизирует. там-то он не считает программиста за "дебила", ага.
                    Ответить
                  • >Авторы бенчмарков зачастую поверхностно знают C/C++ и используют его в «жабьем» стиле
                    Ага, зато когда с++-программисты делают бенчмарки, чтобы доказать, что жаба тормознее, обыкновенно они сами плохо знают жабу и делают всё в приплюснутом виде (и не знают про то, что можно жабу тюнинговать, та же серверная опция убыстряет код порою раза в два). Шило на мыло.

                    >Такие бенчмарки примитивны: они работают только со скалярными типами
                    Тут вообще имхо смешно, если сравнить с предыдущей цитатой. Т.е. если в бенчмарке Жабой используется "скалярный тип" (т.е. грубо говоря работа в стеке + копирования) -- то это неправильный бенчмарк (где жаба выигрывает). Зато вот если в С++ используется стек вместо кучи -- то это правильный бенчмарк (ведь при работе с кучей С++ сильно проигрывает, ибо в Java быстрейший bump-pointer allocator), а на оборотне правильно.

                    Смешная цитата.
                    Ответить
                    • >они сами плохо знают жабу

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

                    Ну это справедливо только для хелловорлдов. Там-то да, пока система запустится, пока всё отджиттится -- дольше времени проходит, чем вывести "Hello, World!" А вот в реальных условиях, т.к. он выполняет только один раз на метод, оверхед настолько мал, что вообще ни на что особо не влияет.

                    >Значит, меряется скорость хорошо оптимизированного динамически скомпилированного кода.

                    Ой-ой-ой, жаба выдала хорошо оптимизированный динамически скомпилированный кода за 1 миллисекунду на час работы приложения. Как нехорошо! Неправильно! *цокает языком* Вот то ли дело С++ -- там плохо оптимизированный статически скомпилированный код -- вот там всё правильно и ок.
                    Ответить
                    • >С++ -- там плохо оптимизированный статически скомпилированный код
                      Такое может быть, только если отключите оптимизацию.
                      Компиляторы с\с++ настолько давно используются, что за это время оптимизаторы успели отточить лучше, чем в любых других языках.
                      Ответить
    • Имхо, это глупо сделано в Java - стектрейс создаётся в конструкторе исключения.
      В C# умнее -- стектрейс заполняется только при throw.

      Ну и само (new Exception()).stackTrace() выглядит как костыль.
      В C# было бы new StackTrace().GetFrame(1).GetMethod() -- причём возвращает не просто имя, а ссылку на объект рефлексии, и там уж делай чё хошь.
      Ответить
    • еще один вариант:
      MethodBase.GetCurrentMethod().Name
      Ответить
      • сорри, не посмотрел, что это Java) такое на Шарпе прокатит)
        Ответить

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