diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-01-04 19:22:31 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-01-04 19:22:31 -0500 |
commit | 7918c9411c01027b096c60c2e245c36591b0076b (patch) | |
tree | f6ee173e6510ebee20cba7104273c1c635708608 | |
parent | b976b2da5c88eed0c47bfbe2cf457330bcb93fa3 (diff) | |
download | roux-7918c9411c01027b096c60c2e245c36591b0076b.tar.gz |
improve performance of bsiter()
-rw-r--r-- | util.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/util.c b/util.c index 5c54c12..380f139 100644 --- a/util.c +++ b/util.c @@ -275,6 +275,32 @@ popcnt(bits b) return b & 0xff; } +inline static int +firstbit(bits b) +{ + int n; + + n = 0; + if (!(b & 0xffffffff)) { + n += 32; + b >>= 32; + } + if (!(b & 0xffff)) { + n += 16; + b >>= 16; + } + if (!(b & 0xff)) { + n += 8; + b >>= 8; + } + if (!(b & 0xf)) { + n += 4; + b >>= 4; + } + n += (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b & 0xf]; + return n; +} + uint bscount(BSet *bs) { @@ -349,18 +375,23 @@ bszero(BSet *bs) int bsiter(BSet *bs, int *elt) { - uint i; + bits b; + uint t, i; - for (i=*elt;; i++) { - while (i < bsmax(bs) && !bs->t[i/NBit]) - i = (i + NBit) & -NBit; - if (i >= bsmax(bs)) + i = *elt; + t = i/NBit; + if (t >= bs->nt) + return 0; + b = bs->t[t]; + b &= ~(BIT(i%NBit) - 1); + while (!b) { + ++t; + if (t >= bs->nt) return 0; - if (bshas(bs, i)) { - *elt = i; - return 1; - } + b = bs->t[t]; } + *elt = NBit*t + firstbit(b); + return 1; } void |