Типы данных Haskell называют "алгебраическими" из-за их соединения с категориальная начальная алгебра . Но тот путь находится безумие.
@olliej: ADTS является на самом деле типами "суммы". Кортежи являются продуктами.
Массив _bitsSetArray256
инициализируется такими значениями, что _bitsSetArray256 [n]
содержит количество битов, установленных в двоичном представлении n
, для n
в 0..255
.
Например, _bitsSetArray256 [13]
равно 3, потому что 13 в двоичном формате равно 1101
, который содержит 3 1
с.
Причина этого заключается в том, что намного быстрее предварительно вычислить эти значения и сохранить их, вместо того, чтобы вычислять их каждый раз ( или по запросу). В конце концов, число 1
с в двоичном представлении числа 13 никогда не изменится :)
Внутри цикла for
мы просматриваем массив из uint
s. AC # uint
- это 32-битная величина, то есть составленная из 4 байтов. Наша таблица поиска сообщает нам, сколько бит установлено в байте, поэтому мы должны обработать каждый из четырех байтов. Манипуляция с битами в строке count + =
извлекает каждый из четырех байтов, а затем получает счетчик битов из поискового массива. Суммирование количества битов для всех четырех байтов дает счетчик битов для uint
в целом.
Таким образом, учитывая BitArray
, эта функция копается в uint [ ] m_array
, затем возвращает общее количество битов, установленных в двоичном представлении uint
в нем.
count + =
извлекает каждый из четырех байтов, а затем получает счетчик битов из поискового массива. Суммирование количества битов для всех четырех байтов дает количество битов для uint
в целом.
Таким образом, для BitArray
эта функция копается в uint [ ] m_array
, затем возвращает общее количество битов, установленных в двоичном представлении uint
в нем.
count + =
извлекает каждый из четырех байтов, а затем получает счетчик битов из поискового массива. Суммирование количества битов для всех четырех байтов дает количество битов для uint
в целом.
Таким образом, для BitArray
эта функция копается в uint [ ] m_array
, затем возвращает общее количество битов, установленных в двоичном представлении uint
в нем.
Я просто хотел опубликовать полезную статью о bitArrays для тех из нас, кто разрабатывает собственные версии Faceting с Lucene.net. См .: http: // dotnetperls.com / precomputed-bitcount
Это хорошее объяснение быстрого способа получения мощности битов включения в виде целого числа (что составляет большую часть того, что делает вышеприведенный пример кода).
Внедрение метода, описанного в статье, в мой фасетный поиск и некоторые другие простые изменения, я смог сократить время, необходимое для получения подсчета, на ~ 65%. Различия в:
Реализация таблицы 65535 против 256 для сдвига 16 бит за раз, а не 8.
private static int [] _bitcounts = InitializeBitcounts ();
private static int GetCardinality (BitArray bitArray)
{
uint [] array = (uint []) bitArray.GetType (). GetField ("m_array", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue (bitArray);
int count = 0;
foreach (значение uint в массиве)
{
count + = _bitcounts [значение & 65535] + _bitcounts [(значение >> 16) & 65535];
}
счетчик возврата;
}
private static int [] InitializeBitcounts ()
{
int [] bitcounts = new int [65536];
int position1 = -1;
int position2 = -1;
//
// Перебираем все элементы и назначить их.
//
for (int i = 1; i <65536; i ++, position1 ++)
{
//
// Настраиваем позиции, из которых мы читаем.
//
if (position1 == position2)
{
position1 = 0;
position2 = i;
}
bitcounts [i] = bitcounts [position1] + 1;
}
вернуть количество битов;
}