1. Си / Говнокод #23426

    +3

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    // https://github.com/vk-com/kphp-kdb/blob/ce6dead5b3345f4b38487cc9e45d55ced3dd7139/bayes/bayes-data.c#L1966
    
    int init_all (kfs_file_handle_t Index) {
      int i;
    
      log_ts_exact_interval = 1;
    
      ltbl_init (&user_table);
    
      bl_head = qmalloc (sizeof (black_list));
      black_list_init (bl_head);
    
      int f = load_header (Index);
    
      jump_log_ts = header.log_timestamp;
      jump_log_pos = header.log_pos1;
      jump_log_crc32 = header.log_pos1_crc32;
    
      int user_cnt = index_users = header.user_cnt;
    
      if (user_cnt < 1000000) {
        user_cnt = 1000000;
      }
    
      assert (user_cnt >= 1000000);
      user_cnt *= 1.1;
    
      while (user_cnt % 2 == 0 || user_cnt % 5 == 0) {
        user_cnt++;
      }
    
      ltbl_set_size (&user_table, user_cnt);
      users = qmalloc (sizeof (user) * user_cnt);
    
      for (i = 0; i < user_cnt; i++) {
        user_init (&users[i]);
      }
    
      LRU_head = users;
      LRU_head->next_used = LRU_head->prev_used = LRU_head;
    
      if (f) {
        try_init_local_uid();
      }
    
      if (index_mode) {
        buff = qmalloc (max_words * sizeof (entry_t));
        new_buff = qmalloc (4000000 * sizeof (entry_t));
      }
    
      return f;
    }

    http://govnokod.ru/23357#comment390273
    > Говорят что в ВК в начале была такая херь: "уже зарегистрировано N" и это N увеличивалось джаваскриптом со случайной скоростью вообще без связи с сервером

    Если я правильно понял, вконтакт продолжает пиздеть по поводу фактического количества зареганых на нем пользовалелей, но теперь делает это на бэкенде

    user_cnt *= 1.1;

    cunt

    Запостил: j123123, 17 Октября 2017

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

    • KFS, So good!

      А вообще, типичный олимпиадный код
      Ответить
    • Неужели один запрос на count такой дорогой?
      Ответить
      • для каждой страницы - да.

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

        Ты думаешь там большая-большая таблица users в реляционной бд?
        Ответить
        • Думаю там самопальная нереляционная велосипедная БД, написанная олимпиадниками, под руководством Егорова. Он об этом сам пейсал.
          В частности http://codeforces.com/blog/entry/53274
          Ответить
          • там такой код везде как в примере выше?

            мама дорогая
            Ответить
            • В каком примере выше?
              Ответить
              • https://github.com/vk-com/kphp-kdb/blob/ce6dead5b3345f4b38487cc9e45d55ced3dd7139/bayes/bayes-data.c#L1966
                Ответить
                • Ага. Хардкод магических констант - наше всё.
                  Можно бесконечно обсирать олимпиадный код, но это бессмысленно.
                  Ответить
                  • Ну вот как мы видим в ВК считают что олимпиадники это круто. Я правда не знаю как они это поддепрживают. Может быть пишут с ноля каждый раз. В любом случае яца у них, вероятно, стальные.
                    Ответить
      • В лоховской MySQL (для примера) запрос count() стоит дёшево только для лоховских таблиц типа MyISAM, потому что там количество строк хранится в заголовке (и именно поэтому в MyISAM при любом изменении данных блокируется вся таблица целиком, ведь каждый раз нужно подправлять заголовок). У таблиц типа InnoDB (поддерживающих транзакции и построчную блокировку) в заголовке нет поля, хранящего количество строк, поэтому такие таблицы при вызове count() перебирают все строки.

        Подозреваю, что и в других СУБД поддержка транзакций и построчной блокировки тоже приведёт к  «дорогому» count().
        Ответить
        • Даже в MySQL MyISAM уже не используют.

          Вообще говоря желание знать количество записей в реальном времени выглядит подозрительно.

          Если это база живых транзакций (OLTP) то в ней конечно могут быть нужны точные данные в реальном времени, но записей там обычно очень мало.

          Если же это база для отчетов/аналитики (OLAP) то там во-первых обычно не нужны данные с точностью до хомячка (хватит и примерно) а если уж нужны то отчет можно построить и за ночь, оффлайново.

          А хранить "активных пользователей сайта" в базе и каждый раз их считать это как-то странно.
          Ответить
          • И мы приходим к выводу, что инкрементить кол-во юзеров в JS - это самое оптимальное.
            Всё равно 99.999% юзеров не догадаются.
            Ответить
            • > Всё равно 99.999% юзеров не догадаются.
              1. Всё равно 99.999% юзерам это число в точном виде не нужно.
              2. Всё равно через пару минут младшие разряды можно выбрасывать.
              Мгновенное количество никому снаружи ВК не нужно, усреднённое за время хорошо аппроксимируется формулой.

              > инкрементить кол-во юзеров в JS - это самое оптимальное
              И, возможно, даже по точности не/не сильно уступает реальному вычислению этого количества.
              Это обоснованная оптимизация, что бы там ни говорили.

              Карл Фридрих Гаусс отмечал: «Недостатки математического образования с наибольшей отчётливостью проявляются в чрезмерной точности численных расчётов».
              Ответить
    • > while (user_cnt % 2 == 0 || user_cnt % 5 == 0)
      Пятого-десятого, второго нам сюда
      Ответить
      • Количество юзеров должно быть не менее 1.1кк и должно заканчиваться на 1, 3, 7 или 9.
        Ответить
        • >>1, 3, 7 или 9
          Потому что это плохая примета?

          А вообще нормально в няшной юзать int когда есть типы явного размера?
          И что такое f ?

          Это чемпион Питера по спортивному программированию среди учащихся 11 классов писал?
          Ответить
          • Среди студентов тоже. Это высшее достижение. См. выше ссылку.
            Ответить
            • Не знаю, если честно.

              Умножать int на не целое чисто это какое-то очень сильное колдунство.
              Ответить
    • if (user_cnt < 1000000) {
        user_cnt = 1000000;
      }
      
      assert (user_cnt >= 1000000);
      user_cnt *= 1.1;

      Очень важный ассерт.

      А что если во вкудахте будет настолько много пользователей, что при умножении их количества на 1.1, будет получаться число, которое в int уже обратно не влазит? Население земного шара - 7,442 миллиарда, это 7 422 000 000, а INT_MAX это на большинстве платформ всего-навсего 2 147 483 647. Ну ок, допустим что во вконтакте зарегалось 2 147 483 000 людей
      int b = 2147483000;
      b *= 1.1;
      printf("%d", b);

      И вот тут 2147483000 умножается на 1.1 (неявно кастуясь при этом в плавучего питуха) и потом кастуется обратно в int, но это число в int не влазит, мы натыкаемся UB, см. https://stackoverflow.com/a/526283

      > To answer your question: The behaviour when you cast out of range floats is undefined or implementation specific.

      > Speaking from experience: I've worked on a MIPS64 system that didn't implemented these kind of casts at all. Instead of doing something deterministic the CPU threw a CPU exception. The exception handler that ought to emulate the cast returned without doing anything to the result.

      В общем, не туда олимпиадники ассерт втулили
      Ответить
    • > qmalloc
      > qfree
      Похоже вконтакте написан на Qt.
      Ответить
      • нет, q значит quick
        вконтакте все очень быстрое просто
        если сортировка то qsort
        если аллокатор то qalloc
        Ответить
        • если sleep то qsleep, поток спит на 9% быстрее
          Ответить
          • Он спит не более чем логарифмическое время.
            Ответить
          • если приспособить к жопе
            сопроцессор фирмы cray
            можно срать в два унитаза
            в сорок тысяч раз быстрей
            Ответить
        • А ssort, salloc должны работать медленнее (s значит slow)?
          Ответить
    • Вконтакте говно собачье!
      Пиздец теперь усложнили свой пиздеж до языка си
      Ответить

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