Каков самый быстрый способ подсчитать все установленные биты?

Как быстрее всего подсчитать все установленные биты?
Число, от которого я считаю биты, от 1<=n<2^63, только положительные значения.

На данный момент я использую набор битов из библиотеки, и это довольно быстро, но если есть более быстрый вариант, я хотел бы знать.

В худшем случае у меня будет более 1 миллиарда итераций, поэтому я ищу способ ускорить его.
Это часть моего цикла, где я подсчитываю установленные биты:

if (std::bitset<64>(currentNumber).count() == numofOnes)
++counter;

Может быть, std::popcount()? (Нужны эксперименты)

MikeCAT 22.12.2020 00:00

Если у вас нет std::popcount() из C++20, см. stackoverflow.com/questions/109023/…

Nate Eldredge 22.12.2020 00:02

Отвечает ли это на ваш вопрос? Как посчитать количество установленных битов в 32-битном целом? - там указан 64-битный ответ, хотя в заголовке указано 32 бита.

Ken Y-N 22.12.2020 00:10

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

spectras 22.12.2020 00:13

Я не фанат "быстрых" вопросов. Чтобы проиллюстрировать, почему и что этот вопрос можно улучшить, позвольте мне предложить для обсуждения следующий ответ: самый быстрый способ — это либо таблица поиска (не для всего диапазона, но иерархически сбалансированная), либо механизм подсчета битов с аппаратной поддержкой. Теперь, пожалуйста, объясните, почему эти два варианта не являются для вас ответом.

Yunnosch 22.12.2020 00:21

Мне очень нравится идея справочной таблицы. Трудно превзойти его по скорости. Займите немного места для хранения.

user4581301 22.12.2020 00:25

Вариант __builtin_popcount медленнее, чем битсет stackoverflow.com/questions/60165922/… Мне придется использовать таблицу поиска, спасибо.

MrRobot 22.12.2020 00:28

Таблица поиска решила мой вопрос, спасибо за совет.

MrRobot 22.12.2020 00:36

@user4581301 user4581301 Размер таблицы поиска можно масштабировать или можно «сбалансировать».

Yunnosch 22.12.2020 00:59

@Yunnosch Да, но они медленнее, чем полная таблица поиска. Аскер хотел самый быстрый, а не самый быстрый с разумной реализацией.

user4581301 22.12.2020 01:00

@MrRobot: Если вы видите комментарии к ответу, на который вы ссылаетесь, «более медленный» результат, вероятно, является артефактом теста, поскольку фактический код сборки одинаков для обоих.

Nate Eldredge 22.12.2020 01:01

Hamming Weight не требует большого объема памяти и работает довольно быстро.

MrRobot 22.12.2020 01:03

@user4581301 user4581301 На самом деле я хотел спровоцировать, упомянув полноразмерную таблицу поиска (очевидно, это не ответ), а затем не смог устоять перед мудрецом о возможности масштабировать ее и сбалансировать скорость и размер. А, ну получился достойный ответ.

Yunnosch 22.12.2020 01:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
13
871
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот демонстрация того, что я имею в виду под сбалансированной таблицей поиска. Этот сильно экономит размер.
Вы можете адаптировать концепцию к таблицам поиска размера, например. 64 или 256, значительно ускоряясь.

#include <iostream>

using namespace std;

int main()
{
   unsigned long long int input=679043ULL; // just a big number, for demo
   
   unsigned char lookup[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
   unsigned char result=0;

   while (input>0)
   {
       cout << (unsigned int) result << " " << (input&15) << " " << input << endl;
       result+=lookup[input&15];
       input>>=4;
   }
   cout << (unsigned int)result << endl;
   return 0;
}

Выход:

0 3 679043
2 8 42440
3 12 2652
5 5 165
7 10 10
9

Выходные данные демо показывают, что цикл накапливается
2 бита в "3",
1 бит в "8",
2 бита в "12",
2 бита в "5",
два бита в "10";
всего 9.

Другие вопросы по теме