unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: Maxime Devos <maximedevos@telenet.be>
Cc: 50456@debbugs.gnu.org
Subject: [bug#50456] Optimise bytevector->nix-base32-string and bytevector->base16-string.
Date: Thu, 09 Sep 2021 16:29:26 +0200	[thread overview]
Message-ID: <87o891esah.fsf@gnu.org> (raw)
In-Reply-To: <7831fcdd8b8aab99cc95ba904076014b4c3cb6d2.camel@telenet.be> (Maxime Devos's message of "Tue, 07 Sep 2021 17:34:28 +0200")

Hello,

Maxime Devos <maximedevos@telenet.be> skribis:

> The two atached patches optimise bytevector->nix-base32-string and
> bytevector->base16-string, making them about 20% and two times
> faster respectively, by reducing allocations.  They are called
> from 'output-path', 'fixed-output-path' and 'store-path'
> in (guix store).

Thanks a lot for looking into this!

> Unfortunately, this does not decrease timings to a noticable degree,
> but it does decrease the allocated memory by 2.3% (*), and it does not
> seem to increase timings.  (See perf-numbers.txt.)

Yeah, base32 code is usually pretty low in profiles of calls to
‘package-derivation’.

> From a93bad629e2746c77446cacddb9986506ce9ba88 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Sun, 5 Sep 2021 16:28:33 +0200
> Subject: [PATCH 1/2] base32: Reduce GC pressure in
>  make-bytevector->base32-string.
>
> The following code has been used to compare performance:
>
> ;; first 20 bytes of sha256 of #vu8(#xde #xad #xbe #xef)
> (define bv #vu8(95 120 195 50 116 228 63 169 222 86 89 38 92 29 145 126 37 192 55 34))
> ,profile
> (let loop ((n 0))
>   (when (< n #e1e6)
>      ((@ (guix base32) bytevector->nix-base32-string) bv)
>      (loop (+ n 1))))
>
> Before this change, the output was:
>
> [...]
> Sample count: 1140
> Total time: 27.465560018 seconds (10.659331433 seconds in GC)
>
> After this change, the output was:
>
> [...]
> Sample count: 957
> Total time: 20.478847143 seconds (6.139721189 seconds in GC)

Note that ,profile (statprof) is intrusive; additional, the REPL uses
the “debug” VM engine, which is slightly slower than the “regular” one
(info "(guile) Command-line Options").

To measure “actual” performance, it’s best to write the code down in a
file and then run:

  time guile -l that-file.scm

or, alternatively, use (ice-9 time) and wrap the body of the relevant
code in (time …), which is a bit more accurate than using the shell’s
‘time’ command since it allows you to dismiss Guile startup time.

(You also need to make sure that the loop counter remains below
‘most-positive-fixnum’, otherwise you’ll end up measuring GC activity
due to the use of bignums, but 10⁶ is definitely OK.)

> * guix/base32.scm
>   (make-bytevector->base32-string): Eliminate 'reverse', use mutation instead.

[...]

> +    (let* ((start (cons #f #f))
> +           (end (quintet-fold (lambda (q r)
> +                                (define pair
> +                                  (cons (vector-ref base32-chars q) #f))
> +                                (set-cdr! r pair)
> +                                pair)
> +                              start
> +                              bv)))
> +      (set-cdr! end '())
> +      (list->string (cdr start)))))

Does replacing (reverse chars) with (reverse! chars) has the same
effect?

I’m reluctant to resorting to micro-optimizations like the one above
since they make code harder to reason about.

> From dfd9b7557e31823320fcbd7abed77de295b7dce1 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 6 Sep 2021 00:46:17 +0200
> Subject: [PATCH 2/2] base16: Reduce GC pressure in bytevector->base16-string.
>
> This makes bytevector->base16-string two times faster.
>
> * guix/base16.scm (bytevector->base16-string): Use utf8->string
>   and iteration instead of string-concatenate and named let.

LGTM.  How did you measure performance for this one?

Thanks,
Ludo’.




  parent reply	other threads:[~2021-09-09 14:30 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-07 15:34 [bug#50456] Optimise bytevector->nix-base32-string and bytevector->base16-string Maxime Devos
2021-09-07 15:36 ` [bug#50456] Base16 and base32 optimisations split off Maxime Devos
2021-09-09 14:29 ` Ludovic Courtès [this message]
2021-09-09 14:42   ` [bug#50456] Optimise bytevector->nix-base32-string and bytevector->base16-string Maxime Devos
2021-09-09 15:15   ` Maxime Devos
     [not found] ` <handler.50456.B.16310288933583.ack@debbugs.gnu.org>
2021-09-07 15:37   ` [bug#50456] Acknowledgement (Optimise bytevector->nix-base32-string and bytevector->base16-string.) Maxime Devos
2021-09-11 15:54   ` bug#50456: " Maxime Devos

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o891esah.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=50456@debbugs.gnu.org \
    --cc=maximedevos@telenet.be \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).