Кресты / Говнокод #18815 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
int turn = m_mapObject->getTurnSpeed();
//НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
if (turn != 0) {
    if (turn > 0) {
    //                    qDebug() << "Turn plus";
        turn /= 45;
        if (turn < 4) turn = 4;
        if (turn > 8) turn = 8;
    } else {
    //                    qDebug() << "Turn minus";
        turn /= 45;
        if (turn > -4) turn = -4;
        if (turn < -8) turn = -8;
    }
    paint.drawLine(QPoint(0,-speed),QPoint(turn,-speed));
}

Вы б знали, как руки чешутся...

Запостил: Antervis Antervis, (Updated )

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

  • На что только не пойдёт байтоёб чтоб сделать за компилятор его работу.
    Ответить
    • нет такого преступления, на которое бы не пошёл байтоёб ради прироста в 2%
      Ответить
      • Обеспечьте байтоёбу 1% прироста, и байтоёб согласен на всякое применение, при 2% он становится оживлённым, при 3% положительно готов сломать себе голову, при 5% он попирает все человеческие законы, при 10% нет такого преступления, на которое он не рискнул бы пойти, хотя бы под страхом некорректной работы программы.
        Ответить
      • > нет такого преступления, на которое бы не пошёл байтоёб ради прироста в 2%
        int turn = m_mapObject->getTurnSpeed();
        // > НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
        // А ПОЧЕМУ БЫ И НЕТ?
        if (turn != 0) {
            int s=turn>>31,a=turn+s^s,b=(a>360?524288:a>180?a*1457:262144)>>16;
            turn=b+s^s;
            paint.drawLine(QPoint(0,-speed),QPoint(turn,-speed));
        }
        Пруф: http://ideone.com/E7ZqWG
        Ответить
        • Добиваем последние условные операторы и мозг читателя:
          int turn = m_mapObject->getTurnSpeed();
          // > НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
          // А ПОЧЕМУ БЫ И НЕТ?
          if (turn != 0) {
              int s=turn>>31,a=turn+s^s,m=a-180>>31,n=a-360>>31,b=262144&m|a*1457&~m&n|524288&~n;
              turn=(b>>16)+s^s;
              paint.drawLine(QPoint(0,-speed),QPoint(turn,-speed));
          }
          Юнит-тест: http://ideone.com/BNHV8p

          bormand кончил и закурил.
          Ответить
          • Финальная версия:
            int turn = m_mapObject->getTurnSpeed();
            // > НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
            // А ПОЧЕМУ БЫ И НЕТ?
            if (turn != 0) {
                int s=turn>>31,a=turn+s^s;
                turn = (a-360>>31&(180-a>>31&(1457*a>>16^4)^12)^8)+s^s;
                paint.drawLine(QPoint(0,-speed),QPoint(turn,-speed));
            }
            Юнит-тест: http://ideone.com/nTKaLF
            Ответить
            • Кстати, прикольный эффект от branch predictor'а - если числа этой функции по порядку скармливать, то мой код работает на 34% медленней оригинала. Но если функцию кормить рандомными числами - на 40% быстрее.
              Ответить
              • Сорри, оптимизацию забыл включить. С -O2 мой код выигрывает 2% при последовательном обходе и 40% при рандомном.
                Ответить
                  • Бля, я понял, разрабы не дают компилякать с -O101, чтобы время не пошло в обратную сторону и не пришлось снова просить Кармака вернуть как было.
                    Кстати, его 10-летний сын написал свою вторую игру, 2k строк на диалекте лиспа.
                    http://1k3c.com
                    К чему это я? Пойду в своё колесо, свернусь комочком и порыдаю над своими тупостью и ленью.
                    Ответить
                    • > чтобы время не пошло в обратную сторону

                      Jeff Dean was forced to invent asynchronous APIs one day when he optimized a function so that it returned before it was invoked.
                      Ответить
              • Используется сакральное знание о машинном представлении чисел с плавающей точкой. Дальше дело побитовой магии.
                Ответить
              • s - знак числа. Когда мы двигаем знаковое число вправо, дырки с левой стороны заполняются знаковым битом. И если мы сдвинем int32_t на 31 бит вправо, мы получим 0xFFFFFFFF (-1) если там был минус и 0x00000000 если плюс или ноль.

                a = abs(turn). Здесь код читается не совсем так, как кажется на первый взгляд - (turn+s)^s, у плюса приоритет больше. При s=0 получается (turn+0)^0 -> turn, при s=-1 получается (turn-1)^(-1) -> ~(turn-1) -> -turn (в процах, емнип, neg через побитовый not так и запилен).

                To be continued...
                Ответить
              • (a-360)>>31 - тот же приём, что и в s, здесь мы определяем знак числа a-360. Т.е. если a>=360, мы получаем 0, а если a<360 - получаем 0xFFFFFFFF.

                (180-a)>>31 - аналогично, если a>180 - 0xFFFFFFFF, иначе 0

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

                To be continued...
                Ответить
              • (1457*a)>>16 - классическое умножение делением. Нам надо поделить на 45, т.е. умножить на 1/45. Подберём ближайшую дробь со знаменателем кратным степени двойки 1/45 ~ 1457/65536. Т.е. чтобы поделить на 45 мы можем умножить на 1457 и поделить на 65536. Деление на 65536 - обычный сдвиг на 16 вправо, ради этого такой красивый знаменатель и выбирался.

                To be continued...
                Ответить
              • Дальше идут "тернарники". Суть идеи в выражении (mask & (a^b)) ^ a. При mask == 0 получаем a, а при mask == 0xFFFFFFF получаем a^b^a, т.е. b. Там два таких тернарника.

                По сути там a > 360 ? 8 : a > 180 ? a / 45 : 4.

                Ну и последнее +s^s восстанавливает знак числа. Вот и всё байтоёбство, ничего особо сложного 🙂
                Ответить
              • Сложный вопрос. Тогда пришлось бы читать том по микрооптимизации. А гцц и сам неплохо раскидывает команды под выбранную архитектуру, поэтому я не стал заморачиваться.
                Ответить
    • Байтоёб как минимум вставил бы else, чтобы устранить лишние проверки, а также вынес бы turn /= 45.
      Ответить
      • > вынес бы turn /= 45
        //НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
        Ответить
  • А я возьму и оптимизирую что-нибудь!
    int turn = m_mapObject->getTurnSpeed();
    //НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
    if (turn != 0) {
            int abs_turn = abs(turn);
            int sign_turn = (turn > 0) ? 1 : -1;
            turn /= 45;
            if (abs_turn > 8) turn = 8 * sign_turn;
            else if (abs_turn < 4) turn = 4 * sign_turn;
    
        // if (turn > 0) {
        //                    qDebug() << "Turn plus";
        // } else {
        //                    qDebug() << "Turn minus";
       // }
    
        paint.drawLine(QPoint(0,-speed),QPoint(turn,-speed));
    }
    Ответить
  • //ВОТ ТУТ ТОЧНО НЕ НАДО ТУТ ОПТИМИЗИРОВАТЬ /= 45 !!!!
    if (turn != 0) {
      switch (turn) {
        case 1: turn /= 45;
        case 3: turn /= 45;
        case 8: turn /= 45;
        default:
          // qDebug() << "Turn-45";
      }
    }
    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8