base32: Provide an open-coded 'bit-field'.

This improves the throughput of 'bytevector->base32-string' a bit.

* guix/base32.scm (bit-field): New macro.
This commit is contained in:
Ludovic Courtès 2021-09-09 23:22:10 +02:00
parent a87d8c912d
commit cb06f7c61e
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2015, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2012, 2015, 2017, 2021 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -42,6 +42,19 @@ (define-module (guix base32)
;;;
;;; 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)