From cb06f7c61e4b8393abf38f1f5891e03c33d53b9b Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 9 Sep 2021 23:22:10 +0200 Subject: base32: Provide an open-coded 'bit-field'. This improves the throughput of 'bytevector->base32-string' a bit. * guix/base32.scm (bit-field): New macro. --- guix/base32.scm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/guix/base32.scm b/guix/base32.scm index 49f191ba26..d6c8a02243 100644 --- a/guix/base32.scm +++ b/guix/base32.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2015, 2017 Ludovic Courtès +;;; Copyright © 2012, 2015, 2017, 2021 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -42,6 +42,19 @@ ;;; ;;; Code: +(define-syntax bit-field + (lambda (s) + ;; This inline version of 'bit-field' assumes that START and END are + ;; literals and pre-computes the mask. In an ideal world, using 'define' + ;; or 'define-inlinable' would be enough, but as of 3.0.7, peval doesn't + ;; expand calls to 'expt' (and 'bit-field' is a subr.) + (syntax-case s () + ((_ n start end) + (let* ((s (syntax->datum #'start)) + (e (syntax->datum #'end)) + (mask (- (expt 2 (- e s)) 1))) + #`(logand (ash n (- start)) #,mask)))))) + (define bytevector-quintet-ref (let* ((ref bytevector-u8-ref) (ref+ (lambda (bv offset) -- cgit v1.2.3