From a6f03ee38f0e735b1a7004a826427e8fe7d7b9d5 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 18 Dec 2012 09:44:22 -0500 Subject: [PATCH] use popcount table --- collects/data/bit-vector.rkt | 16 ++++++++++++++-- collects/data/private/count-bits-in-fixnum.rkt | 7 +++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/collects/data/bit-vector.rkt b/collects/data/bit-vector.rkt index 59595b26a4..56443b494f 100644 --- a/collects/data/bit-vector.rkt +++ b/collects/data/bit-vector.rkt @@ -1,8 +1,9 @@ #lang racket/base (require (for-syntax racket/base) + (for-syntax "private/count-bits-in-fixnum.rkt") racket/private/vector-wraps racket/match - racket/dict + racket/dict racket/contract/base racket/fixnum racket/unsafe/ops @@ -90,9 +91,20 @@ (bit-vector-copy bv start end)])]) bit-vector-copy)) +(define popcount-table + (let () + (define-syntax (make-table stx) + (with-syntax ([(elt ...) + (for/list ([i (in-range 256)]) + (fxpopcount i))]) + ;; Literal immutable vector allocated once (?) + #'(quote #(elt ...)))) + (make-table))) + (define (bit-vector-popcount bv) (for/sum ([b (in-bytes (bit-vector-words bv))]) - (unsafe-fxpopcount* b 8))) + #| (unsafe-fxpopcount* b 8) |# + (unsafe-vector-ref popcount-table b))) (define (bit-vector->list bv) (define len (bit-vector-size bv)) diff --git a/collects/data/private/count-bits-in-fixnum.rkt b/collects/data/private/count-bits-in-fixnum.rkt index 3e85bf65cd..f9b7deb38e 100644 --- a/collects/data/private/count-bits-in-fixnum.rkt +++ b/collects/data/private/count-bits-in-fixnum.rkt @@ -1,6 +1,6 @@ #lang racket/base (require racket/unsafe/ops - (for-syntax racket/base racket/fixnum racket/vector)) + (for-syntax racket/base racket/fixnum)) (provide fxpopcount unsafe-fxpopcount*) ;; Count set bits for 30 bit number in 5 steps. @@ -43,13 +43,12 @@ (cond [(<= bits 8) lut8] [(<= bits 30) lut30] [(<= bits 62) lut62] - [else (raise-syntax-error "bit width too big" stx #'bits0)])] - [flut (vector-map bitwise-not lut)]) + [else (raise-syntax-error "bit width too big" stx #'bits0)])]) ;; Unroll the addition loop #`(let ([n expr]) (let* #,(for/list ([m (in-vector lut)] - [f (in-vector flut)] [b (in-naturals)]) + (define f (bitwise-not m)) #`[n (unsafe-fx+ (unsafe-fxrshift (unsafe-fxand n #,m) #,(fxlshift 1 b)) (unsafe-fxand n #,f))])