tests: Optimize 'fold-available-packages' test.

This test goes from 58s to 10s wall-clock time.

Reported by Maxim Cournoyer <maxim.cournoyer@gmail.com>.

* tests/packages.scm ("fold-available-packages with/without cache"):
Remove 'find-duplicates'.  Add 'list->set*' and use it instead of
'find-duplicates', 'delete-duplicates', and 'lset='.
This commit is contained in:
Ludovic Courtès 2021-02-01 16:07:18 +01:00
parent 93af2ac871
commit 73744725dd
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 ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
@ -42,6 +42,7 @@ (define-module (test-packages)
#:use-module (guix memoization) #:use-module (guix memoization)
#:use-module (guix profiles) #:use-module (guix profiles)
#:use-module (guix scripts package) #:use-module (guix scripts package)
#:use-module (guix sets)
#:use-module (gnu packages) #:use-module (gnu packages)
#:use-module (gnu packages base) #:use-module (gnu packages base)
#:use-module (gnu packages guile) #:use-module (gnu packages guile)
@ -54,6 +55,7 @@ (define-module (test-packages)
#:use-module (srfi srfi-34) #:use-module (srfi srfi-34)
#:use-module (srfi srfi-35) #:use-module (srfi srfi-35)
#:use-module (srfi srfi-64) #:use-module (srfi srfi-64)
#:use-module (srfi srfi-71)
#:use-module (rnrs bytevectors) #:use-module (rnrs bytevectors)
#:use-module (rnrs io ports) #:use-module (rnrs io ports)
#:use-module (ice-9 vlist) #:use-module (ice-9 vlist)
@ -1549,17 +1551,27 @@ (define from-cache
result)) result))
'())))))) '()))))))
(define (find-duplicates l) (define (list->set* lst)
(match l ;; Return two values: LST represented as a set and the list of
(() '()) ;; duplicates in LST.
((head . tail) (let loop ((lst lst)
(if (member head tail) (duplicates '())
(cons head (find-duplicates tail)) (seen (set)))
(find-duplicates tail))))) (match lst
(()
(values seen duplicates))
((head . tail)
(if (set-contains? seen head)
(loop tail (cons head duplicates) seen)
(loop tail duplicates (set-insert head seen)))))))
(pk (find-duplicates from-cache)) ;; Compare FROM-CACHE and NO-CACHE but avoid 'lset=', which exhibits
(and (equal? (delete-duplicates from-cache) from-cache) ;; exponential behavior.
(lset= equal? no-cache from-cache)))) (let ((set1 duplicates1 (list->set* from-cache))
(set2 duplicates2 (list->set* no-cache)))
(and (null? duplicates1) (null? duplicates2)
(every (cut set-contains? set1 <>) no-cache)
(every (cut set-contains? set2 <>) from-cache)))))
(test-assert "find-packages-by-name" (test-assert "find-packages-by-name"
(match (find-packages-by-name "hello") (match (find-packages-by-name "hello")