Commit 5eb7ac0c authored by antirez's avatar antirez
Browse files

Speedup hllRawSum() processing 8 bytes per iteration.

The internal HLL raw encoding used by PFCOUNT when merging multiple keys
is aligned to 8 bits (1 byte per register) so we can exploit this to
improve performances by processing multiple bytes per iteration.

In benchmarks the new code was several times faster with HLLs with many
registers set to zero, while no slowdown was observed with populated
HLLs.
parent 192a2132
...@@ -928,16 +928,24 @@ double hllSparseSum(uint8_t *sparse, int sparselen, double *PE, int *ezp, int *i ...@@ -928,16 +928,24 @@ double hllSparseSum(uint8_t *sparse, int sparselen, double *PE, int *ezp, int *i
double hllRawSum(uint8_t *registers, double *PE, int *ezp) { double hllRawSum(uint8_t *registers, double *PE, int *ezp) {
double E = 0; double E = 0;
int j, ez = 0; int j, ez = 0;
unsigned long reg; uint64_t *word = (uint64_t*) registers;
uint8_t *bytes;
for (j = 0; j < HLL_REGISTERS; j++) { for (j = 0; j < HLL_REGISTERS/8; j++) {
reg = registers[j]; if (*word == 0) {
if (reg == 0) { ez += 8;
ez++;
/* Increment E at the end of the loop. */
} else { } else {
E += PE[reg]; /* Precomputed 2^(-reg[j]). */ bytes = (uint8_t*) word;
if (bytes[0]) E += PE[bytes[0]]; else ez++;
if (bytes[1]) E += PE[bytes[1]]; else ez++;
if (bytes[2]) E += PE[bytes[2]]; else ez++;
if (bytes[3]) E += PE[bytes[3]]; else ez++;
if (bytes[4]) E += PE[bytes[4]]; else ez++;
if (bytes[5]) E += PE[bytes[5]]; else ez++;
if (bytes[6]) E += PE[bytes[6]]; else ez++;
if (bytes[7]) E += PE[bytes[7]]; else ez++;
} }
word++;
} }
E += ez; /* 2^(-reg[j]) is 1 when m is 0, add it 'ez' times for every E += ez; /* 2^(-reg[j]) is 1 when m is 0, add it 'ez' times for every
zero register in the HLL. */ zero register in the HLL. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment