Задать вопрос
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, читал :)
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, да не, в том исходнике я исключительно тестировал за сколько он подберёт нужную хеш функцию )
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, ну я пытался сделать эмуляцию заполнения внутренней хеш таблицы, в данном случае с load_factor = 16/14. Смотрел за сколько попыток в среднем это произойдёт (найдётся h2i что не будет коллизий)
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, она, например, в ClickHouse'е используется для интов + как внутрення часть для cityHash для строк
    ну и я сам посмотрел на некоторых дата-сетах у неё хорошее распределение
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, о, вот это её минус главный, внешняя таблица ~2n, а размер внутренней ~5, если до ближайшей степени 2, то 8, и того 2n * 8 = 16n
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, ты сначала функцией h1 хешируешь во внешнюю хеш таблицу итемы, а потом для каждой ячейки внешней хеш таблицы подбираешь такую h2i, что все итемы ячейки захешируются без коллизий
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, немного не понял как тут поможет кукушка, можно подробнее плз )

    Ну и я про кукушку говорил в контексте того, чтобы contains всегда за O(1), не амортизированно
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, короче выяснил, что для некоторого набора данных (ключей) существуют такие параметры (на картинке - evil_param), что если нарисовать граф, где вершина - это параметр, а ребро - текущий ключ + текущий параметр, то появляется цикл в таком графе

    Поборосял с этим дефолтным способом: если алгоритм сильно много итераций не сходится, то меняю параметр на рандомный и пытаясь заново, вроде работает

    Как я понял, с инкрементальными seed'ами просто вероятность в такой цикл попасть больше

    Граф
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, вот гпт 3.5 дал мне ответ, хотя и довольно поверхностный, хотелось бы мат. обоснование


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

    CRC32 - это циклический редундантный код (Cyclic Redundancy Check), который обычно используется для обнаружения ошибок в данных. Он оперирует с битами данных и вычисляет контрольную сумму для обнаружения ошибок в передаче данных.

    При использовании CRC32 в вашем коде в качестве параметра хеш-функции для хэш-таблицы, вы фактически создаете некоторую последовательность хешей, каждый из которых зависит от предыдущего. Так как CRC32 обрабатывает данные по битам и вычисляет контрольную сумму, его свойства обеспечивают некоторую случайность и разнообразие в вычисленных хеш-значениях.

    Когда вы используете хеш с предыдущей итерации для получения нового хеша (25-я строка), вы создаете последовательность хешей, которая зависит от предыдущих значений. Это приводит к тому, что каждый следующий хеш зависит от предыдущего и от входных данных (ключей), и, таким образом, обеспечивает разнообразие хешей. Кроме того, при каждом исполнении цикла происходит пересчет хеш-значения с новым параметром, что увеличивает разнообразие хешей в процессе.

    С другой стороны, если вы используете обычный инкремент в качестве параметра хеш-функции (40-я строка), то вы просто увеличиваете параметр на 1 на каждой итерации. Это не создает достаточное разнообразие в хеш-значениях для обеспечения успешного поиска хеша без коллизий.

    Таким образом, математическое объяснение заключается в том, что использование CRC32 и его свойства циклического редундантного кода, а также зависимость от предыдущего значения, обеспечивают разнообразие хешей при использовании хеша с предыдущей итерации. Это позволяет алгоритму быстро находить подходящий параметр для успешного заполнения бакета без коллизий.
  • Seed для CRC32?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, ну если всё равновероятно, то 0.25 * 1 + 0.25 * 2 + 0.5 * 2 = 1.75 (0.25 * 1 - элемент есть и он в 1-й ячейке, 0.25 * 2 - элемент есть и он во 2-й ячейке, 0.5 * 2 - элемента нет)
    Предполагается, что contains на одни и те же элементы не вызывается, а если вызывается, то их уже нет в кеше )
  • Идеальное хеширование без чтения из памяти параметров h2(k)?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, ну у фильтра блума вообще будет K кэш миссов в среднем )
    Тут-то я вообще с 2-х до 1-го хочу улучшить
  • Идеальное хеширование без чтения из памяти параметров h2(k)?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, да нет, если какой-то код, в данном случае contains(k), читал дважды из памяти (при этом времени на вычисления тратил совсем немного), то уменьшение количества обращений к памяти в 2 раза увеличит скорость работы этого кода тоже почти вдвое. А contains(k) у PerfectHashTable фактически единственный метод
  • Идеальное хеширование без чтения из памяти параметров h2(k)?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, ну и необязательно справочники, которые содержат данные вроде стран.
    Такая хеш таблица может быть вспомогательной структорой данных в каком-то другом алгоритме, тогда время её1 построения критично.
    Или, например, список каких-то (их не так много, что можно хранить в оперативке, а не на диске) user'ов в оперативной памяти сервера, на старте сервера можно сбилдить таблицу, и запомнить max id (key) user'a, и при запросе contains, если id <= max id, то идти в эту статическую хеш таблицу, иначе в динамическую
  • Идеальное хеширование без чтения из памяти параметров h2(k)?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, так вариант с двумя как раз и противопоставляют варианту с одной, там как раз смысл в том, что квадрат растёт нелинейно и ((m/n)^2)*n (где (m/n)^2 размер бакета) много лучше n^2 (там примерно ((m/n)^2)*n ~ 4n получается при допустимом по времени построения размеру бакета)
  • Идеальное хеширование без чтения из памяти параметров h2(k)?

    Lite_stream
    @Lite_stream Автор вопроса
    mayton2019, забыл упомянуть в самом вопросе, что вариант с размером хеш таблицы m = n^2, где в среднем за 2 раза удастся построить таблицу (только с одной внейшней h1, без h2i) не подходит из-за больших затрат по памяти.

    Ну и что касается, "заранее предпосчитать" это тоже не подходит, если, например, требуется относительно быстрое построение хеш таблицы, где она является частью (шагом) какого-то другого алгоритма. Ну и даже если речь идёт о том, что сбилдить таблицу на старте сервера, то вариант с предподсчётом тоже может не подойти, если не хочется, чтобы сервер стартовал пол часа
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

    Lite_stream
    @Lite_stream Автор вопроса
    Adamos, конкретно по АиСД, если уник норм, например, МФТИ или ИТМО, то они там на высоте, а вот фреймворкдроч как раз (которым промышляют на всяких курсах) не очень, да он и не нужен в вузе, в том же МФТИ фреймворки факультативом являются и не входят в основную программу
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

    Lite_stream
    @Lite_stream Автор вопроса
    Adamos, например, у меня в унике, на структурах данных, их реализовывали через массив байтов, а не T, вроде бы даже аргументируя это чем-то, поэтому так в памяти отложилось и делал через массив байтов. Судя по всему, аргументы были неверны
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

    Lite_stream
    @Lite_stream Автор вопроса
    Adamos, просто до этого, когда писал структуры данных в академических целях, всегда использовал std::byte *, сейчас решил посмотреть, как у других, и везде, что в бусте, что в каком-нибудь EASTL, вижу, что используют именно T *
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

    Lite_stream
    @Lite_stream Автор вопроса
    Adamos, ну да, если компилятор заменит 4-х байтный инт на 8-ми байтный, то количество промахов по кэшу удвоится, но в конкретном случае, что с T *, что с std::byte * размеры массивов (в байтах) одинаковые и влиять не должно
    Или Вы что-то другое имели в виду ?