From e02a6f62e65a46ec8e23ac4499619b190bf1f7ab Mon Sep 17 00:00:00 2001 From: Matteo Landi Date: Sat, 13 Jan 2024 15:21:09 +0100 Subject: [PATCH] Run tests in batches and trigger a GC in between Hopefully this will decrease the likelyhood of running out out of memory --- aoc.asd | 1 + src/utils.lisp | 5 ++++- vendor/make-quickutils.lisp | 1 + vendor/quickutils.lisp | 32 +++++++++++++++++++++++++++----- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/aoc.asd b/aoc.asd index 79f9fc0..7e0a964 100644 --- a/aoc.asd +++ b/aoc.asd @@ -33,6 +33,7 @@ #:pileup #:split-sequence #:st-json + #:trivial-garbage ) :components diff --git a/src/utils.lisp b/src/utils.lisp index 7b8bd6f..ed7bfa4 100644 --- a/src/utils.lisp +++ b/src/utils.lisp @@ -897,7 +897,10 @@ (defvar *tests* nil "A list of tests; the default argument to RUN.") -(defun run () (1am:run *tests*)) +(defun run () + (doseq (tests (subdivide *tests* 100)) + (1am:run *tests*) + (trivial-garbage:gc :full t :verbose t))) (defmacro deftest (name &body body) "Define a test function and add it to `*tests*`." diff --git a/vendor/make-quickutils.lisp b/vendor/make-quickutils.lisp index b45353f..c455196 100644 --- a/vendor/make-quickutils.lisp +++ b/vendor/make-quickutils.lisp @@ -48,6 +48,7 @@ :repeat :string-ends-with-p :string-starts-with-p + :subdivide :subseq- :symb :void diff --git a/vendor/quickutils.lisp b/vendor/quickutils.lisp index 1b7a460..8a1f5f2 100644 --- a/vendor/quickutils.lisp +++ b/vendor/quickutils.lisp @@ -2,7 +2,7 @@ ;;;; See http://quickutil.org for details. ;;;; To regenerate: -;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:KEEP-IF :KEEP-IF-NOT :AAND :AIF :AWHEN :BND* :BND1 :COPY-ARRAY :COPY-HASH-TABLE :DIGITS :DIVF :DOHASH :DOLISTS :DORANGE :DORANGEI :DOSEQ :DOSEQ :DOSUBLISTS :ENUMERATE :FLATTEN :HASH-TABLE-ALIST :HASH-TABLE-KEY-EXISTS-P :HASH-TABLE-KEYS :HASH-TABLE-VALUES :IF-LET :IOTA :LOOPING :MAKE-KEYWORD :MKSTR :MULF :NCYCLE :REPEAT :STRING-ENDS-WITH-P :STRING-STARTS-WITH-P :SUBSEQ- :SYMB :VOID :WHEN-LET :WHILE :WITH-GENSYMS) :ensure-package T :package "AOC.QUICKUTILS") +;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:KEEP-IF :KEEP-IF-NOT :AAND :AIF :AWHEN :BND* :BND1 :COPY-ARRAY :COPY-HASH-TABLE :DIGITS :DIVF :DOHASH :DOLISTS :DORANGE :DORANGEI :DOSEQ :DOSEQ :DOSUBLISTS :ENUMERATE :FLATTEN :HASH-TABLE-ALIST :HASH-TABLE-KEY-EXISTS-P :HASH-TABLE-KEYS :HASH-TABLE-VALUES :IF-LET :IOTA :LOOPING :MAKE-KEYWORD :MKSTR :MULF :NCYCLE :REPEAT :STRING-ENDS-WITH-P :STRING-STARTS-WITH-P :SUBDIVIDE :SUBSEQ- :SYMB :VOID :WHEN-LET :WHILE :WITH-GENSYMS) :ensure-package T :package "AOC.QUICKUTILS") (eval-when (:compile-toplevel :load-toplevel :execute) (unless (find-package "AOC.QUICKUTILS") @@ -27,8 +27,8 @@ :WITH-GENSYMS :LOOPING :MAKE-KEYWORD :MULF :NCYCLE :REPEAT :STRING-ENDS-WITH-P - :STRING-STARTS-WITH-P :SUBSEQ- :VOID - :WHEN-LET :WHILE)))) + :STRING-STARTS-WITH-P :SUBDIVIDE + :SUBSEQ- :VOID :WHEN-LET :WHILE)))) (defmacro abbr (short long) "Defines a new function/macro named `short` and sharing @@ -674,6 +674,28 @@ Examples: (string= prefix s :end2 (length prefix)))) + (defun subdivide (sequence chunk-size) + "Split `sequence` into subsequences of size `chunk-size`." + (check-type sequence sequence) + (check-type chunk-size (integer 1)) + + (etypecase sequence + ;; Since lists have O(N) access time, we iterate through manually, + ;; collecting each chunk as we pass through it. Using SUBSEQ would + ;; be O(N^2). + (list (loop :while sequence + :collect + (loop :repeat chunk-size + :while sequence + :collect (pop sequence)))) + + ;; For other sequences like strings or arrays, we can simply chunk + ;; by repeated SUBSEQs. + (sequence (loop :with len := (length sequence) + :for i :below len :by chunk-size + :collect (subseq sequence i (min len (+ chunk-size i))))))) + + (defun subseq- (seq &optional (start nil) (end nil)) "Like SUBSEQ, except it supports negative indices." (if (not start) @@ -766,7 +788,7 @@ PROGN." dosublists enumerate flatten hash-table-alist hash-table-key-exists-p hash-table-keys hash-table-values if-let iota looping make-keyword mkstr mulf ncycle repeat - string-ends-with-p string-starts-with-p subseq- symb void when-let - when-let* while with-gensyms with-unique-names))) + string-ends-with-p string-starts-with-p subdivide subseq- symb void + when-let when-let* while with-gensyms with-unique-names))) ;;;; END OF quickutils.lisp ;;;;