From 2cb6eb58993b08694f8f5c292451d9d5c02b5648 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 8 Dec 2024 20:54:54 -0600 Subject: [PATCH 01/11] benchmark --- benchmark/insert.lisp | 39 +++++++++++++++++++++++++++++++++++++++ benchmark/package.lisp | 2 ++ rope.asd | 6 ++++++ rope.lisp | 32 ++++++++++++++++---------------- 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 benchmark/insert.lisp create mode 100644 benchmark/package.lisp diff --git a/benchmark/insert.lisp b/benchmark/insert.lisp new file mode 100644 index 0000000..e2fc021 --- /dev/null +++ b/benchmark/insert.lisp @@ -0,0 +1,39 @@ +(in-package #:rope/benchmark) + +;; (progn +;; (sb-ext:restrict-compiler-policy 'speed 3 3) +;; (sb-ext:restrict-compiler-policy 'debug 0 0) +;; ;; (sb-ext:restrict-compiler-policy 'space 0 0) +;; (sb-ext:restrict-compiler-policy 'safety 0 0)) + + +(defparameter *readme* + (merge-pathnames "README.md" (asdf:system-source-directory :rope))) + +(defun print-time (time reps length) + (format t "rope size: ~a, ~a microseconds~%" + length + (* 1000000 (/ time reps)))) + +(defmacro time* (&body body) + `(let ((time)) + (sb-ext:call-with-timing + (lambda (&rest plist) (setf time (getf plist :real-time-ms))) + (lambda () ,@body)) + (coerce (/ time 1000) 'float))) + +(defun benchmark-insert (&optional (reps 1000000)) + (with-open-file (s *readme*) + (let* ((starting-rope (rope:split-rope (rope:make-rope s) 1000)) + (rope starting-rope)) + (dotimes (i 100) + (print-time + (time* + (dotimes (i reps) + (rope:insert-rope rope + (random (rope:rope-length rope)) + "Hello, world!"))) + reps + (rope:rope-length rope)) + (force-output) + (setf rope (rope:concat-rope rope starting-rope)))))) diff --git a/benchmark/package.lisp b/benchmark/package.lisp new file mode 100644 index 0000000..07229ff --- /dev/null +++ b/benchmark/package.lisp @@ -0,0 +1,2 @@ +(defpackage #:rope/benchmark + (:use #:cl)) diff --git a/rope.asd b/rope.asd index 7f6100f..2a3529a 100644 --- a/rope.asd +++ b/rope.asd @@ -20,6 +20,12 @@ (print result) (assert (eql t stat))))) +(asdf:defsystem #:rope/benchmark + :depends-on (#:rope) + :components ((:module "benchmark" + :components ((:file "package") + (:file "insert"))))) + (asdf:defsystem #:rope/dev :depends-on (#:cl-dot #:rope) :components ((:module "dev" diff --git a/rope.lisp b/rope.lisp index e2d1a9e..13c2747 100644 --- a/rope.lisp +++ b/rope.lisp @@ -35,6 +35,18 @@ ;; Utils ;; ;;-------;; +(defun branch-weight (branch) + (rope-length (branch-left branch))) + +(defun leaf-short-p (leaf) + (>= *short-leaf* (rope-length leaf))) + +(defun strcat (a b) + (concatenate 'string a b)) + +(defun make-leaf (string &optional length) + (make-instance 'leaf :string string :length (or length (length string)))) + (defgeneric make-rope (source) (:documentation "Create a new rope from a string, stream, or pathname.") (:method ((source rope)) @@ -43,7 +55,7 @@ (labels ((read-leaves (&optional acc) (let* ((string (make-string *long-leaf*)) (length (read-sequence string source)) - (leaf (make-instance 'leaf :length length :string (subseq string 0 length)))) + (leaf (make-leaf (subseq string 0 length) length))) (if (= *long-leaf* length) (read-leaves (cons leaf acc)) (cons leaf acc))))) @@ -57,19 +69,7 @@ (if (<= *long-leaf* length) (concat-rope (make-rope (subseq source 0 (round length 2))) (make-rope (subseq source (round length 2)))) - (make-instance 'leaf :length length :string source))))) - -(defgeneric rope-weight (rope) - (:method ((rope leaf)) - (rope-length rope)) - (:method ((rope branch)) - (rope-length (branch-left rope)))) - -(defun leaf-short-p (leaf) - (>= *short-leaf* (rope-length leaf))) - -(defun strcat (a b) - (concatenate 'string a b)) + (make-leaf source length))))) ;;-----------;; ;; Iteration ;; @@ -175,7 +175,7 @@ (:method ((rope leaf) index) (char (leaf-string rope) index)) (:method ((rope branch) index) - (let ((weight (rope-weight rope))) + (let ((weight (branch-weight rope))) (if (< index weight) (index-rope (branch-left rope) index) (index-rope (branch-right rope) (- index weight)))))) @@ -212,7 +212,7 @@ (make-rope (subseq (leaf-string rope) index)))) (:method ((rope branch) index) (with-slots (left right) rope - (let ((weight (rope-weight rope))) + (let ((weight (branch-weight rope))) (cond ((= index weight) (values left right)) ((< index weight) From f67b556476fe3145aad31d9a52a290aec96a22da Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 8 Dec 2024 21:01:32 -0600 Subject: [PATCH 02/11] rearrange benchmarks into dev dir --- dev/benchmark.lisp | 37 +++++++++++++++++++++++++++++++++++++ dev/graphviz.lisp | 10 +++++----- dev/package.lisp | 5 ++++- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 dev/benchmark.lisp diff --git a/dev/benchmark.lisp b/dev/benchmark.lisp new file mode 100644 index 0000000..5b6ec8b --- /dev/null +++ b/dev/benchmark.lisp @@ -0,0 +1,37 @@ +(in-package #:rope/dev) + +;; (progn +;; (sb-ext:restrict-compiler-policy 'speed 3 3) +;; (sb-ext:restrict-compiler-policy 'debug 0 0) +;; ;; (sb-ext:restrict-compiler-policy 'space 0 0) +;; (sb-ext:restrict-compiler-policy 'safety 0 0)) + + +(defparameter *readme* + (merge-pathnames "README.md" (asdf:system-source-directory :rope))) + +(defun print-time (time reps length) + (format t "rope size: ~a, ~a microseconds~%" + length + (* 1000000 (/ time reps)))) + +(defmacro time* (&body body) + `(let ((time)) + (sb-ext:call-with-timing + (lambda (&rest plist) (setf time (getf plist :real-time-ms))) + (lambda () ,@body)) + (coerce (/ time 1000) 'float))) + +(defun benchmark-insert (&optional (reps 1000000)) + (with-open-file (s *readme*) + (let* ((starting-rope (split-rope (make-rope s) 1000)) + (rope starting-rope)) + (dotimes (i 100) + (print-time + (time* + (dotimes (i reps) + (insert-rope rope (random (rope-length rope)) "Hello, world!"))) + reps + (rope-length rope)) + (force-output) + (setf rope (concat-rope rope starting-rope)))))) diff --git a/dev/graphviz.lisp b/dev/graphviz.lisp index 7be198d..ea9be26 100644 --- a/dev/graphviz.lisp +++ b/dev/graphviz.lisp @@ -22,21 +22,21 @@ (let ((obj (root-rope obj))) (graph-object-points-to self obj))) -(defmethod graph-object-node ((self (eql 'rope)) (obj branch)) +(defmethod graph-object-node ((self (eql 'rope)) (obj rope::branch)) (make-instance 'node :attributes `(:label ,(format nil "length: ~a~%depth: ~a" (rope-length obj) (rope-depth obj))))) -(defmethod graph-object-points-to ((self (eql 'rope)) (obj branch)) +(defmethod graph-object-points-to ((self (eql 'rope)) (obj rope::branch)) (list (make-instance 'attributed - :object (branch-right obj) + :object (rope::branch-right obj) :attributes `(:label "R")) (make-instance 'attributed - :object (branch-left obj) + :object (rope::branch-left obj) :attributes `(:label "L")))) -(defmethod graph-object-node ((self (eql 'rope)) (obj leaf)) +(defmethod graph-object-node ((self (eql 'rope)) (obj rope::leaf)) (make-instance 'node :attributes `(:label ,(format nil "~a" (rope::leaf-string obj)) diff --git a/dev/package.lisp b/dev/package.lisp index c8bd8ea..5f11841 100644 --- a/dev/package.lisp +++ b/dev/package.lisp @@ -1,4 +1,7 @@ (defpackage #:rope/dev (:use #:cl #:cl-dot #:rope) (:export - #:graph-ropes)) + ;; graphviz.lisp + #:graph-ropes + ;; benchmark.lisp + )) From e5f784bdf460cf6319f97ee1601f7ddbe2761a6b Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Wed, 11 Dec 2024 11:32:11 -0600 Subject: [PATCH 03/11] test --- .github/workflows/ci-test.yaml | 7 ++++-- benchmark/insert.lisp | 39 ---------------------------------- benchmark/package.lisp | 2 -- dev/package.lisp | 1 + rope.asd | 11 +++------- 5 files changed, 9 insertions(+), 51 deletions(-) delete mode 100644 benchmark/insert.lisp delete mode 100644 benchmark/package.lisp diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index efbac1d..bb606c4 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -10,12 +10,15 @@ jobs: - name: Checkout Repository uses: actions/checkout@v3 - name: Run Tests + env: + COVERALLS: 'true' + COVERALLS_REPO_TOKEN: 'COVERALLS_REPO_TOKEN=AjlQRo6hsAc6TsTv0tTXXW1AWR0MuFJQP' run: | set -ex sbcl --disable-debugger \ --load /root/quicklisp/setup.lisp \ --eval '(ql:update-all-dists)' \ --load rope.asd \ - --eval '(ql:quickload :rope/test)' \ - --eval '(asdf:test-system :rope/test)' \ + --eval '(ql:quickload :rope/test :silent t)' \ + --eval '(coveralls:with-coveralls () (asdf:test-system :rope/test))' \ --eval '(quit)' \ No newline at end of file diff --git a/benchmark/insert.lisp b/benchmark/insert.lisp deleted file mode 100644 index e2fc021..0000000 --- a/benchmark/insert.lisp +++ /dev/null @@ -1,39 +0,0 @@ -(in-package #:rope/benchmark) - -;; (progn -;; (sb-ext:restrict-compiler-policy 'speed 3 3) -;; (sb-ext:restrict-compiler-policy 'debug 0 0) -;; ;; (sb-ext:restrict-compiler-policy 'space 0 0) -;; (sb-ext:restrict-compiler-policy 'safety 0 0)) - - -(defparameter *readme* - (merge-pathnames "README.md" (asdf:system-source-directory :rope))) - -(defun print-time (time reps length) - (format t "rope size: ~a, ~a microseconds~%" - length - (* 1000000 (/ time reps)))) - -(defmacro time* (&body body) - `(let ((time)) - (sb-ext:call-with-timing - (lambda (&rest plist) (setf time (getf plist :real-time-ms))) - (lambda () ,@body)) - (coerce (/ time 1000) 'float))) - -(defun benchmark-insert (&optional (reps 1000000)) - (with-open-file (s *readme*) - (let* ((starting-rope (rope:split-rope (rope:make-rope s) 1000)) - (rope starting-rope)) - (dotimes (i 100) - (print-time - (time* - (dotimes (i reps) - (rope:insert-rope rope - (random (rope:rope-length rope)) - "Hello, world!"))) - reps - (rope:rope-length rope)) - (force-output) - (setf rope (rope:concat-rope rope starting-rope)))))) diff --git a/benchmark/package.lisp b/benchmark/package.lisp deleted file mode 100644 index 07229ff..0000000 --- a/benchmark/package.lisp +++ /dev/null @@ -1,2 +0,0 @@ -(defpackage #:rope/benchmark - (:use #:cl)) diff --git a/dev/package.lisp b/dev/package.lisp index 5f11841..9cbcb3e 100644 --- a/dev/package.lisp +++ b/dev/package.lisp @@ -4,4 +4,5 @@ ;; graphviz.lisp #:graph-ropes ;; benchmark.lisp + #:benchmark-insert )) diff --git a/rope.asd b/rope.asd index 2a3529a..8f901b9 100644 --- a/rope.asd +++ b/rope.asd @@ -7,7 +7,7 @@ :in-order-to ((test-op (test-op #:rope/test)))) (asdf:defsystem #:rope/test - :depends-on (#:alexandria #:fiasco #:rope) + :depends-on (#:alexandria #:fiasco #:cl-coveralls #:rope) :components ((:module "test" :components ((:file "basic") (:file "fuzz")))) @@ -20,14 +20,9 @@ (print result) (assert (eql t stat))))) -(asdf:defsystem #:rope/benchmark - :depends-on (#:rope) - :components ((:module "benchmark" - :components ((:file "package") - (:file "insert"))))) - (asdf:defsystem #:rope/dev :depends-on (#:cl-dot #:rope) :components ((:module "dev" :components ((:file "package") - (:file "graphviz"))))) + (:file "graphviz") + (:file "benchmark"))))) From ed4d20cb290cbc10888e1e5708568107a98a504c Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Wed, 11 Dec 2024 11:36:16 -0600 Subject: [PATCH 04/11] asdf --- .github/workflows/ci-test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index bb606c4..c0143d3 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -9,6 +9,8 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v3 + - name: Install Git + run: apt update && apt install -y git - name: Run Tests env: COVERALLS: 'true' From cba0527c15e5d0793e3a20d9ca1598a9bfee4ede Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Thu, 12 Dec 2024 23:37:49 -0600 Subject: [PATCH 05/11] rotato --- dev/benchmark.lisp | 3 ++ dev/graphviz.lisp | 13 +++-- rope.lisp | 120 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 104 insertions(+), 32 deletions(-) diff --git a/dev/benchmark.lisp b/dev/benchmark.lisp index 5b6ec8b..2e6c73f 100644 --- a/dev/benchmark.lisp +++ b/dev/benchmark.lisp @@ -26,6 +26,9 @@ (with-open-file (s *readme*) (let* ((starting-rope (split-rope (make-rope s) 1000)) (rope starting-rope)) + (dotimes (i 9999) + (setf rope (concat-rope rope starting-rope))) + (setf starting-rope rope) (dotimes (i 100) (print-time (time* diff --git a/dev/graphviz.lisp b/dev/graphviz.lisp index ea9be26..919a99b 100644 --- a/dev/graphviz.lisp +++ b/dev/graphviz.lisp @@ -3,7 +3,7 @@ (defparameter *string* "In computer programming, a rope, or cord, is a data structure composed of smaller strings that is used to efficiently store and manipulate longer strings or entire texts.") (defparameter rope::*long-leaf* 24) -(defparameter rope::*short-leaf* 8) +(defparameter rope::*short-leaf* 2) (defclass root () ((name :initarg :name :accessor root-name) @@ -15,7 +15,7 @@ :attributes `(:label ,(format nil "rope: ~a~%length: ~a~%depth: ~a" (root-name root) (rope-length obj) - (rope-depth obj)) + (rope::rope-depth obj)) :style :filled)))) (defmethod graph-object-points-to ((self (eql 'rope)) (obj root)) @@ -26,7 +26,7 @@ (make-instance 'node :attributes `(:label ,(format nil "length: ~a~%depth: ~a" (rope-length obj) - (rope-depth obj))))) + (rope::rope-depth obj))))) (defmethod graph-object-points-to ((self (eql 'rope)) (obj rope::branch)) (list (make-instance 'attributed @@ -75,3 +75,10 @@ (setf rope (append-rope rope " we can do it again")) (setf rope (append-rope rope " later!")) (graph-ropes (list rope))) + +#+example +(let ((rope (rope::make-rope "hello world"))) + (dotimes (i 10) + (setf rope (rope:append-rope rope "!"))) + (graph-ropes (list (rope::balance-rope rope) + ))) diff --git a/rope.lisp b/rope.lisp index 13c2747..fc74f48 100644 --- a/rope.lisp +++ b/rope.lisp @@ -101,6 +101,77 @@ ;; Balancing ;; ;;-----------;; +;; Balance: -2 +;; Left Rotation +;; a c +;; / \ / \ +;; b c a e +;; / \ / \ / \ +;; d e b d f g +;; / \ +;; f g + +;; Balance: 2 +;; Right Rotation +;; a b +;; / \ / \ +;; b c d a +;; / \ / \ / \ +;; d e f g e c +;; / \ +;; f g + +(defgeneric rotate (rope direction) + (:method ((rope branch) (direction (eql :left))) + (with-slots (left right) rope + (concat-rope* + (concat-rope* left (branch-left right)) + (branch-right right)))) + (:method ((rope branch) (direction (eql :right))) + (with-slots (left right) rope + (concat-rope* + (branch-left left) + (concat-rope* (branch-right left) right))))) + +(defmethod rotate :around (rope direction) + (format t "rope: ~a, rotating: ~a~%" (write-rope rope nil) direction) + (call-next-method)) + +(defgeneric balance-direction (rope) + (:method ((rope leaf)) + nil) + (:method ((rope branch)) + (with-slots (left right) rope + (let ((balance (- (rope-depth left) (rope-depth right)))) + (cond ((< 1 balance) :right) + ((> -1 balance) :left) + (t nil)))))) + +;; (defmethod balance :around (rope) +;; (let ((bal (call-next-method))) +;; (format t "rope: ~a, balance: ~a~%" (write-rope rope nil) bal) +;; bal)) + +(defgeneric balance-rope (rope) + (:method ((rope leaf)) + rope) + (:method ((rope branch)) + (with-slots (left right) rope + (let* ((left (if (balance-direction left) (balance-rope left) left)) + (right (if (balance-direction right) (balance-rope right) right)) + (rope (concat-rope* left right)) + (balance (balance rope))) + (cond ((< 1 balance) + (rotate rope :right)) + ((> -1 balance) + (rotate rope :left)) + (t + rope)))))) + +;;---------;; +;; Rebuild ;; +;;---------;; + (defun normalize-leaves (leaves &optional carry) (let ((leaf (car leaves))) (cond ((and carry (null leaf)) @@ -115,16 +186,6 @@ (t (cons leaf (normalize-leaves (cdr leaves))))))) -(defgeneric balancedp (rope) - (:documentation "Check if a rope is a height-balanced tree.") - (:method ((rope leaf)) - t) - (:method ((rope branch)) - (with-slots (left right) rope - (and (balancedp left) - (balancedp right) - (>= 2 (abs (- (rope-depth left) (rope-depth right)))))))) - (defun merge-leaves (leaves start end) (let ((range (- end start))) (case range @@ -134,12 +195,10 @@ (concat-rope (merge-leaves leaves start mid) (merge-leaves leaves mid end))))))) -(defun balance-rope (rope &optional forcep) +(defun rebuild-rope (rope) "Balance a rope by reconstructing it from the bottom up." - (if (and (balancedp rope) (not forcep)) - rope - (let ((leaves (normalize-leaves (collect-rope rope)))) - (merge-leaves leaves 0 (length leaves))))) + (let ((leaves (normalize-leaves (collect-rope rope)))) + (merge-leaves leaves 0 (length leaves)))) ;;--------;; ;; Insert ;; @@ -147,17 +206,17 @@ (defgeneric prepend-rope (rope source) (:documentation "Return a new rope with a string or rope inserted at the beginning of a rope.") - (:method (rope (source string)) - (concat-rope (make-rope source) rope)) (:method (rope (source rope)) - (concat-rope source rope))) + (concat-rope source rope)) + (:method (rope (source t)) + (concat-rope (make-rope source) rope))) (defgeneric append-rope (rope source) (:documentation "Return a new rope with a string or rope inserted at the end of a rope.") - (:method (rope (source string)) - (concat-rope rope (make-rope source))) (:method (rope (source rope)) - (concat-rope rope source))) + (concat-rope rope source)) + (:method (rope (source t)) + (concat-rope rope (make-rope source)))) (defun insert-rope (rope index str) "Return a new rope with a string or rope inserted at the specified index of a rope." @@ -192,14 +251,17 @@ ;; Concat ;; ;;--------;; +(defun concat-rope* (left right) + "Concatenates without balancing." + (make-instance 'branch + :length (+ (rope-length left) (rope-length right)) + :depth (1+ (max (rope-depth left) (rope-depth right))) + :left left + :right right)) + (defun concat-rope (left right) "Returns a balanced concatenation of two ropes." - (balance-rope - (make-instance 'branch - :length (+ (rope-length left) (rope-length right)) - :depth (1+ (max (rope-depth left) (rope-depth right))) - :left left - :right right))) + (balance-rope (concat-rope* left right))) ;;-------;; ;; Split ;; @@ -218,10 +280,10 @@ ((< index weight) (multiple-value-bind (ante post) (split-rope left index) (values (balance-rope ante) - (balance-rope (concat-rope post right))))) + (concat-rope post right)))) ((> index weight) (multiple-value-bind (ante post) (split-rope right (- index weight)) - (values (balance-rope (concat-rope left ante)) + (values (concat-rope left ante) (balance-rope post))))))))) ;;------;; From bb51ece9c66b697589379fe20967a17e58601bd9 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sat, 14 Dec 2024 22:31:11 -0600 Subject: [PATCH 06/11] fixed? --- dev/graphviz.lisp | 6 ++- rope.lisp | 111 ++++++++++++++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 39 deletions(-) diff --git a/dev/graphviz.lisp b/dev/graphviz.lisp index 919a99b..ab6b91f 100644 --- a/dev/graphviz.lisp +++ b/dev/graphviz.lisp @@ -78,7 +78,9 @@ #+example (let ((rope (rope::make-rope "hello world"))) - (dotimes (i 10) + (dotimes (i 15) (setf rope (rope:append-rope rope "!"))) - (graph-ropes (list (rope::balance-rope rope) + ;; (dotimes (i 15) + ;; (setf rope (rope::balance-rope rope))) + (graph-ropes (list rope ))) diff --git a/rope.lisp b/rope.lisp index fc74f48..de3cbc8 100644 --- a/rope.lisp +++ b/rope.lisp @@ -121,52 +121,89 @@ ;; / \ ;; f g -(defgeneric rotate (rope direction) - (:method ((rope branch) (direction (eql :left))) - (with-slots (left right) rope - (concat-rope* - (concat-rope* left (branch-left right)) - (branch-right right)))) - (:method ((rope branch) (direction (eql :right))) - (with-slots (left right) rope - (concat-rope* - (branch-left left) - (concat-rope* (branch-right left) right))))) - -(defmethod rotate :around (rope direction) - (format t "rope: ~a, rotating: ~a~%" (write-rope rope nil) direction) - (call-next-method)) - -(defgeneric balance-direction (rope) +(defgeneric balance-factor (rope) (:method ((rope leaf)) - nil) + 0) (:method ((rope branch)) - (with-slots (left right) rope - (let ((balance (- (rope-depth left) (rope-depth right)))) - (cond ((< 1 balance) :right) - ((> -1 balance) :left) - (t nil)))))) - -;; (defmethod balance :around (rope) -;; (let ((bal (call-next-method))) -;; (format t "rope: ~a, balance: ~a~%" (write-rope rope nil) bal) -;; bal)) + (- (rope-depth (branch-left rope)) + (rope-depth (branch-right rope))))) + +(defun rotate-left (rope) + (with-slots (left right) rope + (concat-rope* + (concat-rope left (branch-left right)) + (branch-right right)))) + +(defun rotate-right (rope) + (with-slots (left right) rope + (concat-rope* + (branch-left left) + (concat-rope (branch-right left) right)))) + +(defun rotate-left-right (rope) + (with-slots (left right) rope + (rotate-right (concat-rope* (rotate-left left) right)))) + +(defun rotate-right-left (rope) + (with-slots (left right) rope + (rotate-left (concat-rope* left (rotate-right right))))) + +(defun balance-children (rope) + (with-slots (left right) rope + (concat-rope* (balance-rope left) + (balance-rope right)))) (defgeneric balance-rope (rope) (:method ((rope leaf)) rope) (:method ((rope branch)) (with-slots (left right) rope - (let* ((left (if (balance-direction left) (balance-rope left) left)) - (right (if (balance-direction right) (balance-rope right) right)) - (rope (concat-rope* left right)) - (balance (balance rope))) - (cond ((< 1 balance) - (rotate rope :right)) - ((> -1 balance) - (rotate rope :left)) + (let ((bf (balance-factor rope))) + (cond ((< 0 bf) + ;; (balance-children) + (if (minusp (balance-factor left)) + (rotate-left-right rope) + (rotate-right rope))) + ((> 0 bf) + ;; (balance-children) + (if (plusp (balance-factor right)) + (rotate-right-left rope) + (rotate-left rope))) (t - rope)))))) + rope)))) + ;; (with-slots (left right) rope + ;; (let ((left (if (zerop (balance-factor left)) + ;; left + ;; (balance-rope left))) + ;; (right (if (zerop (balance-factor right)) + ;; right + ;; (balance-rope right))) + ;; (rope (concat-rope* left right)) + ;; (bf (balance-factor rope))) + ;; (format t "root: ~a, left: ~a, right: ~a~%" + ;; bf + ;; (balance-factor left) + ;; (balance-factor right) + ;; ) + ;; (cond ((< 0 bf) + ;; (if (minusp (balance-factor left)) + ;; (rotate-left-right rope) + ;; (rotate-right rope))) + ;; ((> 0 bf) + ;; (if (plusp (balance-factor right)) + ;; (rotate-right-left rope) + ;; (rotate-left rope))) + ;; (t + ;; rope)))) + ;; (with-slots (left right) rope + ;; (let* ((left (if (balance-direction left) (balance-rope left) left)) + ;; (right (if (balance-direction right) (balance-rope right) right)) + ;; (rope (concat-rope* left right)) + ;; (balance (balance rope))) + ;; (cond ((< 1 balance) (rotate rope :right)) + ;; ((> -1 balance) (rotate rope :left)) + ;; (t rope)))) + )) ;;---------;; ;; Rebuild ;; From e00692389a17d3d1daaa041411cd7b611089a056 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sat, 14 Dec 2024 22:32:20 -0600 Subject: [PATCH 07/11] rotato --- rope.lisp | 57 +------------------------------------------------------ 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/rope.lisp b/rope.lisp index de3cbc8..3b9a9ab 100644 --- a/rope.lisp +++ b/rope.lisp @@ -101,26 +101,6 @@ ;; Balancing ;; ;;-----------;; -;; Balance: -2 -;; Left Rotation -;; a c -;; / \ / \ -;; b c a e -;; / \ / \ / \ -;; d e b d f g -;; / \ -;; f g - -;; Balance: 2 -;; Right Rotation -;; a b -;; / \ / \ -;; b c d a -;; / \ / \ / \ -;; d e f g e c -;; / \ -;; f g - (defgeneric balance-factor (rope) (:method ((rope leaf)) 0) @@ -160,50 +140,15 @@ (with-slots (left right) rope (let ((bf (balance-factor rope))) (cond ((< 0 bf) - ;; (balance-children) (if (minusp (balance-factor left)) (rotate-left-right rope) (rotate-right rope))) ((> 0 bf) - ;; (balance-children) (if (plusp (balance-factor right)) (rotate-right-left rope) (rotate-left rope))) (t - rope)))) - ;; (with-slots (left right) rope - ;; (let ((left (if (zerop (balance-factor left)) - ;; left - ;; (balance-rope left))) - ;; (right (if (zerop (balance-factor right)) - ;; right - ;; (balance-rope right))) - ;; (rope (concat-rope* left right)) - ;; (bf (balance-factor rope))) - ;; (format t "root: ~a, left: ~a, right: ~a~%" - ;; bf - ;; (balance-factor left) - ;; (balance-factor right) - ;; ) - ;; (cond ((< 0 bf) - ;; (if (minusp (balance-factor left)) - ;; (rotate-left-right rope) - ;; (rotate-right rope))) - ;; ((> 0 bf) - ;; (if (plusp (balance-factor right)) - ;; (rotate-right-left rope) - ;; (rotate-left rope))) - ;; (t - ;; rope)))) - ;; (with-slots (left right) rope - ;; (let* ((left (if (balance-direction left) (balance-rope left) left)) - ;; (right (if (balance-direction right) (balance-rope right) right)) - ;; (rope (concat-rope* left right)) - ;; (balance (balance rope))) - ;; (cond ((< 1 balance) (rotate rope :right)) - ;; ((> -1 balance) (rotate rope :left)) - ;; (t rope)))) - )) + rope)))))) ;;---------;; ;; Rebuild ;; From aa40e44c9cdd63e7b968b6b010896b016802779d Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sat, 14 Dec 2024 22:35:16 -0600 Subject: [PATCH 08/11] fix workflow --- .github/workflows/ci-test.yaml | 11 +++-------- dev/graphviz.lisp | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index c0143d3..4f5fe6b 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -9,18 +9,13 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v3 - - name: Install Git - run: apt update && apt install -y git - name: Run Tests - env: - COVERALLS: 'true' - COVERALLS_REPO_TOKEN: 'COVERALLS_REPO_TOKEN=AjlQRo6hsAc6TsTv0tTXXW1AWR0MuFJQP' run: | set -ex sbcl --disable-debugger \ --load /root/quicklisp/setup.lisp \ --eval '(ql:update-all-dists)' \ --load rope.asd \ - --eval '(ql:quickload :rope/test :silent t)' \ - --eval '(coveralls:with-coveralls () (asdf:test-system :rope/test))' \ - --eval '(quit)' \ No newline at end of file + --eval '(ql:quickload :rope/test)' \ + --eval '(asdf:test-system :rope/test)' \ + --eval '(quit)'name: ci-test \ No newline at end of file diff --git a/dev/graphviz.lisp b/dev/graphviz.lisp index ab6b91f..67681ab 100644 --- a/dev/graphviz.lisp +++ b/dev/graphviz.lisp @@ -80,7 +80,7 @@ (let ((rope (rope::make-rope "hello world"))) (dotimes (i 15) (setf rope (rope:append-rope rope "!"))) - ;; (dotimes (i 15) - ;; (setf rope (rope::balance-rope rope))) + (dotimes (i 5) + (setf rope (rope:insert-rope rope 8 "@"))) (graph-ropes (list rope ))) From afa85d1da1cb816b79dafb9456d1453164cda26e Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sat, 14 Dec 2024 22:38:22 -0600 Subject: [PATCH 09/11] fix workflow --- .github/workflows/ci-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index 4f5fe6b..efbac1d 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -18,4 +18,4 @@ jobs: --load rope.asd \ --eval '(ql:quickload :rope/test)' \ --eval '(asdf:test-system :rope/test)' \ - --eval '(quit)'name: ci-test \ No newline at end of file + --eval '(quit)' \ No newline at end of file From 702263f7a89b89ba7f1d8dd7e0630abf1713b513 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sat, 14 Dec 2024 22:39:43 -0600 Subject: [PATCH 10/11] fix workflow --- rope.asd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rope.asd b/rope.asd index 8f901b9..4f997b9 100644 --- a/rope.asd +++ b/rope.asd @@ -7,7 +7,7 @@ :in-order-to ((test-op (test-op #:rope/test)))) (asdf:defsystem #:rope/test - :depends-on (#:alexandria #:fiasco #:cl-coveralls #:rope) + :depends-on (#:alexandria #:fiasco #:rope) :components ((:module "test" :components ((:file "basic") (:file "fuzz")))) From 360d29d587cab2e1954180268e0090ad4598ddba Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 15 Dec 2024 00:15:49 -0600 Subject: [PATCH 11/11] benchmarks --- README.md | 7 ++++ dev/benchmark.lisp | 63 ++++++++++++++++++++++++------ dev/package.lisp | 2 + rope.asd | 2 +- screenshots/insert-benchmark.png | Bin 0 -> 153549 bytes test/fuzz.lisp | 64 +++++++++++++++++++++++++------ 6 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 screenshots/insert-benchmark.png diff --git a/README.md b/README.md index a413f47..4d05086 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,13 @@ Get chars or strings at a position: (print (rope:substr-rope rope 10 15))) ``` +# Performance + +Time to insert is a good measure since it splits and concatenates. +This graph demonstrates O(log(n)) performance: + +![Insert Benchmark](screenshots/insert-benchmark.png) + # Dev Utils If you want to generate graphs as shown above, you will need to diff --git a/dev/benchmark.lisp b/dev/benchmark.lisp index 2e6c73f..3a2494f 100644 --- a/dev/benchmark.lisp +++ b/dev/benchmark.lisp @@ -6,6 +6,20 @@ ;; ;; (sb-ext:restrict-compiler-policy 'space 0 0) ;; (sb-ext:restrict-compiler-policy 'safety 0 0)) +(defun random-rope (total-length) + (with-open-file (source "/dev/urandom" :element-type '(unsigned-byte 8)) + (labels ((read-leaves (&optional acc (acc-length 0)) + (let* ((string* (make-array (min rope::*long-leaf* (- total-length acc-length)) + :element-type '(unsigned-byte 8))) + (length (read-sequence string* source)) + (string (map 'string #'code-char string*)) + (leaf (rope::make-leaf (subseq string 0 length) length))) + (if (and (= rope::*long-leaf* length) + (not (= total-length (+ length acc-length)))) + (read-leaves (cons leaf acc) (+ length acc-length)) + (cons leaf acc))))) + (let ((leaves (nreverse (read-leaves)))) + (rope::merge-leaves leaves 0 (length leaves)))))) (defparameter *readme* (merge-pathnames "README.md" (asdf:system-source-directory :rope))) @@ -13,7 +27,8 @@ (defun print-time (time reps length) (format t "rope size: ~a, ~a microseconds~%" length - (* 1000000 (/ time reps)))) + (* 1000000 (/ time reps))) + (force-output)) (defmacro time* (&body body) `(let ((time)) @@ -22,19 +37,43 @@ (lambda () ,@body)) (coerce (/ time 1000) 'float))) -(defun benchmark-insert (&optional (reps 1000000)) - (with-open-file (s *readme*) - (let* ((starting-rope (split-rope (make-rope s) 1000)) - (rope starting-rope)) - (dotimes (i 9999) - (setf rope (concat-rope rope starting-rope))) - (setf starting-rope rope) - (dotimes (i 100) +(defun benchmark-size (size step times reps) + (let ((rope (random-rope size)) + (step (random-rope step))) + (dotimes (i times) + (sb-ext:gc :full t) + (print-time + (time* + (dotimes (i reps) + (insert-rope rope (random (rope-length rope)) "Hello, world!"))) + reps + (rope-length rope)) + (setf rope (concat-rope rope step))))) + +(defun benchmark-log (start-size limit reps) + (let ((rope (random-rope start-size)) + (step (random-rope start-size))) + (dotimes (i limit) + (dotimes (i 10) + (unless (= i 0) + (setf rope (insert-rope rope + (random (rope-length rope)) + step))) + (sb-ext:gc :full t) (print-time (time* (dotimes (i reps) (insert-rope rope (random (rope-length rope)) "Hello, world!"))) reps - (rope-length rope)) - (force-output) - (setf rope (concat-rope rope starting-rope)))))) + (rope-length rope))) + (setf step rope)))) + +(defun benchmark-insert (&optional (reps 1000000)) + (setf rope::*long-leaf* 512) + (benchmark-log 1000 6 reps) + ;; (benchmark-size 10000 10000 10 reps) + ;; (benchmark-size 100000 10000 10 reps) + ;; (benchmark-size 1000000 100000 10 reps) + ;; (benchmark-size 10000000 1000000 10 reps) + ;; (benchmark-size 100000000 10000000 100 reps) + ) diff --git a/dev/package.lisp b/dev/package.lisp index 9cbcb3e..57815e3 100644 --- a/dev/package.lisp +++ b/dev/package.lisp @@ -1,5 +1,7 @@ (defpackage #:rope/dev (:use #:cl #:cl-dot #:rope) + (:local-nicknames + (#:a #:alexandria)) (:export ;; graphviz.lisp #:graph-ropes diff --git a/rope.asd b/rope.asd index 4f997b9..09fc3e2 100644 --- a/rope.asd +++ b/rope.asd @@ -21,7 +21,7 @@ (assert (eql t stat))))) (asdf:defsystem #:rope/dev - :depends-on (#:cl-dot #:rope) + :depends-on (#:alexandria #:cl-dot #:rope) :components ((:module "dev" :components ((:file "package") (:file "graphviz") diff --git a/screenshots/insert-benchmark.png b/screenshots/insert-benchmark.png new file mode 100644 index 0000000000000000000000000000000000000000..17d5b0e7f6c74907bc0c536c7eb3fafbf588072e GIT binary patch literal 153549 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ɯ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 literal 0 HcmV?d00001 diff --git a/test/fuzz.lisp b/test/fuzz.lisp index 2fbff30..e8c6fab 100644 --- a/test/fuzz.lisp +++ b/test/fuzz.lisp @@ -11,6 +11,29 @@ :length (1- length) :acc (rope::strcat acc (string (a:random-elt *charset*)))))) +(defun random-rope (total-length) + (with-open-file (source "/dev/urandom" :element-type '(unsigned-byte 8)) + (labels ((read-leaves (&optional acc (acc-length 0)) + (let* ((string* (make-array (min rope::*long-leaf* (- total-length acc-length)) + :element-type '(unsigned-byte 8))) + (length (read-sequence string* source)) + (string (map 'string #'code-char string*)) + (leaf (rope::make-leaf (subseq string 0 length) length))) + (if (and (= rope::*long-leaf* length) + (not (= total-length (+ length acc-length)))) + (read-leaves (cons leaf acc) (+ length acc-length)) + (cons leaf acc))))) + (let ((leaves (nreverse (read-leaves)))) + (rope::merge-leaves leaves 0 (length leaves)))))) + +(defgeneric balancedp (rope) + (:method ((rope rope::leaf)) + t) + (:method ((rope rope::branch)) + (and (>= 1 (abs (rope::balance-factor rope))) + (balancedp (rope::branch-left rope)) + (balancedp (rope::branch-right rope))))) + (deftest fuzz-basic-tests () "Run the basic test suite with different leaf sizes." (loop :for i :from 1 :to 64 @@ -20,17 +43,19 @@ (is (run-tests :rope/test/basic))))) (deftest fuzz-split () - (dotimes (i 10) + (dotimes (i 1000) (let* ((length (random 10000)) (string (random-string :length length)) (rope (rope:make-rope string)) (index (random length))) (multiple-value-bind (ante post) (rope:split-rope rope index) + (is (balancedp ante)) + (is (balancedp post)) (is (string= (subseq string 0 index) (rope:write-rope ante nil))) (is (string= (subseq string index) (rope:write-rope post nil))))))) (deftest fuzz-index () - (dotimes (i 100) + (dotimes (i 1000) (let* ((length (1+ (random 1000))) (string (random-string :length length)) (rope (rope:make-rope string)) @@ -38,21 +63,38 @@ (is (char= (char string index) (rope:index-rope rope index)))))) (deftest fuzz-concat () - (dotimes (i 100) + (dotimes (i 1000) (let* ((string-a (random-string :length (random 1000))) (string-b (random-string :length (random 1000))) (rope-a (rope:make-rope string-a)) - (rope-b (rope:make-rope string-b))) - (is (string= (rope::strcat string-a string-b) - (rope:write-rope (rope:concat-rope rope-a rope-b) nil)))))) + (rope-b (rope:make-rope string-b)) + (new-string (rope::strcat string-a string-b)) + (new-rope (rope:concat-rope rope-a rope-b))) + (is (balancedp new-rope)) + (is (string= new-string (rope:write-rope new-rope nil)))))) (deftest fuzz-kill () - (dotimes (i 10000) + (dotimes (i 1000) (let* ((length (+ 10 (random 1000))) (string (random-string :length length)) (rope (rope:make-rope string)) (end (1+ (random (1- length)))) - (start (random end))) - (is (string= (rope::strcat (subseq string 0 start) - (subseq string end)) - (rope:write-rope (rope:kill-rope rope start end) nil)))))) + (start (random end)) + (new-string (rope::strcat (subseq string 0 start) (subseq string end))) + (new-rope (rope:kill-rope rope start end))) + (is (balancedp new-rope)) + (is (string= new-string (rope:write-rope new-rope nil)))))) + +#+ignore +(deftest fuzz-insert-balance () + (setf rope::*long-leaf* 128) + (dotimes (i 10) + (let ((rope (random-rope 1000))) + (dotimes (i 100) + (setf rope + (rope:insert-rope rope + (random (rope:rope-length rope)) + (random-string :length (random 512)))) + (unless (balancedp rope) + (return-from fuzz-insert-balance rope)) + (is (balancedp rope))))))