diff --git a/bench/base64-decode-perf.scm b/bench/base64-decode-perf.scm new file mode 100644 index 00000000..433075c0 --- /dev/null +++ b/bench/base64-decode-perf.scm @@ -0,0 +1,79 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; base64-decode 性能基准:仅测统一入口 base64-decode(按参数类型分发到 string / bytevector) + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-ascii-string n) + (let ((out (open-output-string))) + (do ((i 0 (+ i 1))) + ((= i n)) + (display (integer->char (+ 97 (modulo i 26))) out) + ) ;do + (get-output-string out) + ) ;let +) ;define + +(define (build-binary-bv n) + (let ((bv (make-bytevector n))) + (do ((i 0 (+ i 1))) + ((= i n)) + (bytevector-u8-set! bv i (modulo (* i 31) 256)) + ) ;do + bv + ) ;let +) ;define + +(define medium-n 1024) + +(define ascii-medium (build-ascii-string medium-n)) + +(define bv-medium (build-binary-bv medium-n)) + +(define enc-ascii-medium (string-base64-encode ascii-medium)) + +(define enc-bv-medium (bytevector-base64-encode bv-medium)) + +(define iter 15) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (base64-decode enc-ascii-medium) + (base64-decode enc-bv-medium) +) ;do + +(display "=== base64-decode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (base64-decode enc-ascii-medium)) '() iter))) + (report "base64-decode string(1KB)" iter t) +) ;let +(let ((t (timeit (lambda () (base64-decode enc-bv-medium)) '() iter))) + (report "base64-decode bytevector(1KB)" iter t) +) ;let diff --git a/bench/base64-encode-perf.scm b/bench/base64-encode-perf.scm new file mode 100644 index 00000000..d166787e --- /dev/null +++ b/bench/base64-encode-perf.scm @@ -0,0 +1,75 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; base64-encode 性能基准:仅测统一入口 base64-encode(按参数类型分发到 string / bytevector) + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-ascii-string n) + (let ((out (open-output-string))) + (do ((i 0 (+ i 1))) + ((= i n)) + (display (integer->char (+ 97 (modulo i 26))) out) + ) ;do + (get-output-string out) + ) ;let +) ;define + +(define (build-binary-bv n) + (let ((bv (make-bytevector n))) + (do ((i 0 (+ i 1))) + ((= i n)) + (bytevector-u8-set! bv i (modulo (* i 31) 256)) + ) ;do + bv + ) ;let +) ;define + +(define medium-n 1024) + +(define ascii-medium (build-ascii-string medium-n)) + +(define bv-medium (build-binary-bv medium-n)) + +(define iter 30) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (base64-encode ascii-medium) + (base64-encode bv-medium) +) ;do + +(display "=== base64-encode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (base64-encode ascii-medium)) '() iter))) + (report "base64-encode string(1KB)" iter t) +) ;let +(let ((t (timeit (lambda () (base64-encode bv-medium)) '() iter))) + (report "base64-encode bytevector(1KB)" iter t) +) ;let diff --git a/bench/base64-perf.scm b/bench/base64-perf.scm deleted file mode 100644 index b0dda1e8..00000000 --- a/bench/base64-perf.scm +++ /dev/null @@ -1,271 +0,0 @@ -;; -;; Copyright (C) 2026 The Goldfish Scheme Authors -;; -;; Licensed under the Apache License, Version 2.0 (the "License"); -;; you may not use this file except in compliance with the License. -;; You may obtain a copy of the License at -;; -;; http://www.apache.org/LICENSE-2.0 -;; -;; Unless required by applicable law or agreed to in writing, software -;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -;; License for the specific language governing permissions and limitations -;; under the License. -;; - -(import (liii base) (liii base64) (liii timeit)) - -(define (build-ascii-string n) - (let ((out (open-output-string))) - (do ((i 0 (+ i 1))) - ((= i n)) - (display (integer->char (+ 97 (modulo i 26))) out) - ) ;do - (get-output-string out) - ) ;let -) ;define - -(define (build-binary-bv n) - (let ((bv (make-bytevector n))) - (do ((i 0 (+ i 1))) - ((= i n)) - (bytevector-u8-set! bv i (modulo (* i 31) 256)) - ) ;do - bv - ) ;let -) ;define - -(define tiny-n 8) - -(define small-n 100) - -(define medium-n 1024) - -(define large-n (* 10 1024)) - -(define ascii-tiny (build-ascii-string tiny-n)) - -(define ascii-small (build-ascii-string small-n)) - -(define ascii-medium (build-ascii-string medium-n)) - -(define ascii-large (build-ascii-string large-n)) - -(define bv-tiny (build-binary-bv tiny-n)) - -(define bv-small (build-binary-bv small-n)) - -(define bv-medium (build-binary-bv medium-n)) - -(define bv-large (build-binary-bv large-n)) - -(define enc-ascii-tiny (string-base64-encode ascii-tiny)) - -(define enc-ascii-small (string-base64-encode ascii-small)) - -(define enc-ascii-medium (string-base64-encode ascii-medium)) - -(define enc-ascii-large (string-base64-encode ascii-large)) - -(define enc-bv-tiny (bytevector-base64-encode bv-tiny)) - -(define enc-bv-small (bytevector-base64-encode bv-small)) - -(define enc-bv-medium (bytevector-base64-encode bv-medium)) - -(define enc-bv-large (bytevector-base64-encode bv-large)) - -(define (report title iterations time-val) - (display "[") - (display title) - (display "] iterations=") - (display iterations) - (display " time=") - (display time-val) - (display "s") - (newline) -) ;define - -(do ((i 0 (+ i 1))) - ((= i 5)) - (string-base64-encode ascii-small) - (string-base64-decode enc-ascii-small) - (bytevector-base64-encode bv-small) - (bytevector-base64-decode enc-bv-small) -) ;do - -(define str-enc-tiny-iter 3000) - -(define str-enc-small-iter 300) - -(define str-enc-medium-iter 30) - -(define str-enc-large-iter 3) - -(define str-decode-tiny-iter 1500) - -(define str-decode-small-iter 150) - -(define str-decode-medium-iter 15) - -(define str-decode-large-iter 2) - -(define bv-enc-tiny-iter 3000) - -(define bv-enc-small-iter 300) - -(define bv-enc-medium-iter 30) - -(define bv-enc-large-iter 3) - -(define bv-decode-tiny-iter 1500) - -(define bv-decode-small-iter 150) - -(define bv-decode-medium-iter 15) - -(define bv-decode-large-iter 2) - -(define unified-enc-iter 30) - -(define unified-decode-iter 15) - -(display "=== (liii base64) 性能基准测试 ===") -(newline) -(newline) - -(display "--- string-base64-encode ---") -(newline) -(let ((t (timeit (lambda () (string-base64-encode ascii-tiny)) '() str-enc-tiny-iter)) - ) ; - (report "string-base64-encode tiny(8B)" str-enc-tiny-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-encode ascii-small)) '() str-enc-small-iter) - ) ;t - ) ; - (report "string-base64-encode small(100B)" str-enc-small-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-encode ascii-medium)) '() str-enc-medium-iter) - ) ;t - ) ; - (report "string-base64-encode medium(1KB)" str-enc-medium-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-encode ascii-large)) '() str-enc-large-iter) - ) ;t - ) ; - (report "string-base64-encode large(10KB)" str-enc-large-iter t) -) ;let -(newline) - -(display "--- string-base64-decode ---") -(newline) -(let ((t (timeit (lambda () (string-base64-decode enc-ascii-tiny)) - '() - str-decode-tiny-iter - ) ;timeit - ) ;t - ) ; - (report "string-base64-decode tiny(8B)" str-decode-tiny-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-decode enc-ascii-small)) - '() - str-decode-small-iter - ) ;timeit - ) ;t - ) ; - (report "string-base64-decode small(100B)" str-decode-small-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-decode enc-ascii-medium)) - '() - str-decode-medium-iter - ) ;timeit - ) ;t - ) ; - (report "string-base64-decode medium(1KB)" str-decode-medium-iter t) -) ;let -(let ((t (timeit (lambda () (string-base64-decode enc-ascii-large)) - '() - str-decode-large-iter - ) ;timeit - ) ;t - ) ; - (report "string-base64-decode large(10KB)" str-decode-large-iter t) -) ;let -(newline) - -(display "--- bytevector-base64-encode ---") -(newline) -(let ((t (timeit (lambda () (bytevector-base64-encode bv-tiny)) '() bv-enc-tiny-iter)) - ) ; - (report "bytevector-base64-encode tiny(8B)" bv-enc-tiny-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-encode bv-small)) '() bv-enc-small-iter) - ) ;t - ) ; - (report "bytevector-base64-encode small(100B)" bv-enc-small-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-encode bv-medium)) '() bv-enc-medium-iter) - ) ;t - ) ; - (report "bytevector-base64-encode medium(1KB)" bv-enc-medium-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-encode bv-large)) '() bv-enc-large-iter) - ) ;t - ) ; - (report "bytevector-base64-encode large(10KB)" bv-enc-large-iter t) -) ;let -(newline) - -(display "--- bytevector-base64-decode ---") -(newline) -(let ((t (timeit (lambda () (bytevector-base64-decode enc-bv-tiny)) - '() - bv-decode-tiny-iter - ) ;timeit - ) ;t - ) ; - (report "bytevector-base64-decode tiny(8B)" bv-decode-tiny-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-decode enc-bv-small)) - '() - bv-decode-small-iter - ) ;timeit - ) ;t - ) ; - (report "bytevector-base64-decode small(100B)" bv-decode-small-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-decode enc-bv-medium)) - '() - bv-decode-medium-iter - ) ;timeit - ) ;t - ) ; - (report "bytevector-base64-decode medium(1KB)" bv-decode-medium-iter t) -) ;let -(let ((t (timeit (lambda () (bytevector-base64-decode enc-bv-large)) - '() - bv-decode-large-iter - ) ;timeit - ) ;t - ) ; - (report "bytevector-base64-decode large(10KB)" bv-decode-large-iter t) -) ;let -(newline) - -(display "--- base64-encode / base64-decode 统一入口 ---") -(newline) -(let ((t (timeit (lambda () (base64-encode ascii-medium)) '() unified-enc-iter))) - (report "base64-encode string(1KB)" unified-enc-iter t) -) ;let -(let ((t (timeit (lambda () (base64-encode bv-medium)) '() unified-enc-iter))) - (report "base64-encode bytevector(1KB)" unified-enc-iter t) -) ;let -(let ((t (timeit (lambda () (base64-decode enc-ascii-medium)) '() unified-decode-iter) - ) ;t - ) ; - (report "base64-decode string(1KB)" unified-decode-iter t) -) ;let -(let ((t (timeit (lambda () (base64-decode enc-bv-medium)) '() unified-decode-iter))) - (report "base64-decode bytevector(1KB)" unified-decode-iter t) -) ;let diff --git a/bench/bytevector-base64-decode-perf.scm b/bench/bytevector-base64-decode-perf.scm new file mode 100644 index 00000000..d86110e5 --- /dev/null +++ b/bench/bytevector-base64-decode-perf.scm @@ -0,0 +1,94 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; bytevector-base64-decode 性能基准:仅测 bytevector-base64-decode 一个函数 + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-binary-bv n) + (let ((bv (make-bytevector n))) + (do ((i 0 (+ i 1))) + ((= i n)) + (bytevector-u8-set! bv i (modulo (* i 31) 256)) + ) ;do + bv + ) ;let +) ;define + +(define tiny-n 8) + +(define small-n 100) + +(define medium-n 1024) + +(define large-n (* 10 1024)) + +(define bv-tiny (build-binary-bv tiny-n)) + +(define bv-small (build-binary-bv small-n)) + +(define bv-medium (build-binary-bv medium-n)) + +(define bv-large (build-binary-bv large-n)) + +(define enc-tiny (bytevector-base64-encode bv-tiny)) + +(define enc-small (bytevector-base64-encode bv-small)) + +(define enc-medium (bytevector-base64-encode bv-medium)) + +(define enc-large (bytevector-base64-encode bv-large)) + +(define tiny-iter 1500) + +(define small-iter 150) + +(define medium-iter 15) + +(define large-iter 2) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (bytevector-base64-decode enc-small) +) ;do + +(display "=== bytevector-base64-decode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (bytevector-base64-decode enc-tiny)) '() tiny-iter))) + (report "bytevector-base64-decode tiny(8B)" tiny-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-decode enc-small)) '() small-iter))) + (report "bytevector-base64-decode small(100B)" small-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-decode enc-medium)) '() medium-iter))) + (report "bytevector-base64-decode medium(1KB)" medium-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-decode enc-large)) '() large-iter))) + (report "bytevector-base64-decode large(10KB)" large-iter t) +) ;let diff --git a/bench/bytevector-base64-encode-perf.scm b/bench/bytevector-base64-encode-perf.scm new file mode 100644 index 00000000..f2a40b5c --- /dev/null +++ b/bench/bytevector-base64-encode-perf.scm @@ -0,0 +1,86 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; bytevector-base64-encode 性能基准:仅测 bytevector-base64-encode 一个函数 + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-binary-bv n) + (let ((bv (make-bytevector n))) + (do ((i 0 (+ i 1))) + ((= i n)) + (bytevector-u8-set! bv i (modulo (* i 31) 256)) + ) ;do + bv + ) ;let +) ;define + +(define tiny-n 8) + +(define small-n 100) + +(define medium-n 1024) + +(define large-n (* 10 1024)) + +(define bv-tiny (build-binary-bv tiny-n)) + +(define bv-small (build-binary-bv small-n)) + +(define bv-medium (build-binary-bv medium-n)) + +(define bv-large (build-binary-bv large-n)) + +(define tiny-iter 3000) + +(define small-iter 300) + +(define medium-iter 30) + +(define large-iter 3) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (bytevector-base64-encode bv-small) +) ;do + +(display "=== bytevector-base64-encode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (bytevector-base64-encode bv-tiny)) '() tiny-iter))) + (report "bytevector-base64-encode tiny(8B)" tiny-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-encode bv-small)) '() small-iter))) + (report "bytevector-base64-encode small(100B)" small-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-encode bv-medium)) '() medium-iter))) + (report "bytevector-base64-encode medium(1KB)" medium-iter t) +) ;let +(let ((t (timeit (lambda () (bytevector-base64-encode bv-large)) '() large-iter))) + (report "bytevector-base64-encode large(10KB)" large-iter t) +) ;let diff --git a/bench/string-base64-decode-perf.scm b/bench/string-base64-decode-perf.scm new file mode 100644 index 00000000..5c5ac791 --- /dev/null +++ b/bench/string-base64-decode-perf.scm @@ -0,0 +1,94 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; string-base64-decode 性能基准:仅测 string-base64-decode 一个函数 + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-ascii-string n) + (let ((out (open-output-string))) + (do ((i 0 (+ i 1))) + ((= i n)) + (display (integer->char (+ 97 (modulo i 26))) out) + ) ;do + (get-output-string out) + ) ;let +) ;define + +(define tiny-n 8) + +(define small-n 100) + +(define medium-n 1024) + +(define large-n (* 10 1024)) + +(define ascii-tiny (build-ascii-string tiny-n)) + +(define ascii-small (build-ascii-string small-n)) + +(define ascii-medium (build-ascii-string medium-n)) + +(define ascii-large (build-ascii-string large-n)) + +(define enc-tiny (string-base64-encode ascii-tiny)) + +(define enc-small (string-base64-encode ascii-small)) + +(define enc-medium (string-base64-encode ascii-medium)) + +(define enc-large (string-base64-encode ascii-large)) + +(define tiny-iter 1500) + +(define small-iter 150) + +(define medium-iter 15) + +(define large-iter 2) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (string-base64-decode enc-small) +) ;do + +(display "=== string-base64-decode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (string-base64-decode enc-tiny)) '() tiny-iter))) + (report "string-base64-decode tiny(8B)" tiny-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-decode enc-small)) '() small-iter))) + (report "string-base64-decode small(100B)" small-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-decode enc-medium)) '() medium-iter))) + (report "string-base64-decode medium(1KB)" medium-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-decode enc-large)) '() large-iter))) + (report "string-base64-decode large(10KB)" large-iter t) +) ;let diff --git a/bench/string-base64-encode-perf.scm b/bench/string-base64-encode-perf.scm new file mode 100644 index 00000000..54596600 --- /dev/null +++ b/bench/string-base64-encode-perf.scm @@ -0,0 +1,86 @@ +;; +;; Copyright (C) 2026 The Goldfish Scheme Authors +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations +;; under the License. +;; + +;; string-base64-encode 性能基准:仅测 string-base64-encode 一个函数 + +(import (liii base) (liii base64) (liii timeit)) + +(define (build-ascii-string n) + (let ((out (open-output-string))) + (do ((i 0 (+ i 1))) + ((= i n)) + (display (integer->char (+ 97 (modulo i 26))) out) + ) ;do + (get-output-string out) + ) ;let +) ;define + +(define tiny-n 8) + +(define small-n 100) + +(define medium-n 1024) + +(define large-n (* 10 1024)) + +(define ascii-tiny (build-ascii-string tiny-n)) + +(define ascii-small (build-ascii-string small-n)) + +(define ascii-medium (build-ascii-string medium-n)) + +(define ascii-large (build-ascii-string large-n)) + +(define tiny-iter 3000) + +(define small-iter 300) + +(define medium-iter 30) + +(define large-iter 3) + +(define (report title iterations time-val) + (display "[") + (display title) + (display "] iterations=") + (display iterations) + (display " time=") + (display time-val) + (display "s") + (newline) +) ;define + +(do ((i 0 (+ i 1))) + ((= i 5)) + (string-base64-encode ascii-small) +) ;do + +(display "=== string-base64-encode 性能基准测试 ===") +(newline) +(newline) + +(let ((t (timeit (lambda () (string-base64-encode ascii-tiny)) '() tiny-iter))) + (report "string-base64-encode tiny(8B)" tiny-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-encode ascii-small)) '() small-iter))) + (report "string-base64-encode small(100B)" small-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-encode ascii-medium)) '() medium-iter))) + (report "string-base64-encode medium(1KB)" medium-iter t) +) ;let +(let ((t (timeit (lambda () (string-base64-encode ascii-large)) '() large-iter))) + (report "string-base64-encode large(10KB)" large-iter t) +) ;let diff --git a/devel/0081.md b/devel/0081.md new file mode 100644 index 00000000..0e2995ac --- /dev/null +++ b/devel/0081.md @@ -0,0 +1,67 @@ +# [0081] base64 单元测试与 perf 拆分 + +## 任务相关的代码文件 +- tests/liii/base64/bytevector-base64-encode-test.scm (新增) +- goldfish/liii/base64.scm (被测实现,未改动) +- bench/base64-perf.scm (删除) +- bench/string-base64-encode-perf.scm (新增) +- bench/string-base64-decode-perf.scm (新增) +- bench/bytevector-base64-encode-perf.scm (新增) +- bench/bytevector-base64-decode-perf.scm (新增) +- bench/base64-encode-perf.scm (新增) +- bench/base64-decode-perf.scm (新增) + +## 如何测试 +``` +xmake config --yes +xmake b goldfish +bin/gf fmt tests/liii/base64/bytevector-base64-encode-test.scm +bin/gf tests/liii/base64/bytevector-base64-encode-test.scm +bin/gf tests/liii/base64/bytevector-base64-decode-test.scm +bin/gf tests/liii/base64/base64-encode-test.scm +bin/gf tests/liii/base64/base64-decode-test.scm +bin/gf bench/string-base64-encode-perf.scm +bin/gf bench/string-base64-decode-perf.scm +bin/gf bench/bytevector-base64-encode-perf.scm +bin/gf bench/bytevector-base64-decode-perf.scm +bin/gf bench/base64-encode-perf.scm +bin/gf bench/base64-decode-perf.scm +``` + +## 2026/06/28 base64 性能基准拆分到以函数为单位 +### What +把原 `bench/base64-perf.scm`(一个文件混测 6 个函数)拆成 6 个以函数为单位的独立 bench 文件,每个文件自包含辅助函数、数据构建、各档迭代次数,可独立运行。 + +1. 新增 `bench/string-base64-encode-perf.scm`:仅测 `string-base64-encode`,tiny/small/medium/large 四档 +2. 新增 `bench/string-base64-decode-perf.scm`:仅测 `string-base64-decode`,tiny/small/medium/large 四档 +3. 新增 `bench/bytevector-base64-encode-perf.scm`:仅测 `bytevector-base64-encode`,tiny/small/medium/large 四档 +4. 新增 `bench/bytevector-base64-decode-perf.scm`:仅测 `bytevector-base64-decode`,tiny/small/medium/large 四档 +5. 新增 `bench/base64-encode-perf.scm`:仅测统一入口 `base64-encode`,medium 一档(string + bytevector) +6. 新增 `bench/base64-decode-perf.scm`:仅测统一入口 `base64-decode`,medium 一档(string + bytevector) +7. 删除原 `bench/base64-perf.scm` + +### Why +原 `bench/base64-perf.scm` 把 6 个函数塞在同一个文件里:定位某个函数的耗时需要在长输出里翻找,单独重测某个函数要跑整套(debug 构建下约 9s),且后续 `bytevector-base64-encode` 下沉到 native 时(见后续任务)只想盯单函数的 before/after 对比,混测文件不便于做这种聚焦回归。拆成以函数为单位后,单函数 perf 可独立运行、独立对比。 + +### How +- 每个文件沿用原文件的迭代次数档位(encode 系 tiny=3000/small=300/medium=30/large=3;decode 系减半;统一入口 medium=30 或 15) +- 每个文件自带 `build-ascii-string` / `build-binary-bv` 与对应规模数据,避免相互依赖 +- decode 类 bench 在文件内先用对应 encode 函数生成 `enc-*` 数据,再进入计时 +- 统一入口 `base64-encode` / `base64-decode` 只测 medium 一档(它们只是按参数类型转发到上面 4 个函数) + +## 2026/06/28 为 bytevector-base64-encode 新增单元测试 +### What +仿照 [0079](0079.md) 为 `bytevector-base64-decode` 单独建立测试文件的做法,为 `bytevector-base64-encode` 新建 `tests/liii/base64/bytevector-base64-encode-test.scm`,共 22 个 check,作为后续把 encode 也下沉到 native C++ 的回归基线。 + +1. 新增 `tests/liii/base64/bytevector-base64-encode-test.scm`,覆盖空输入、RFC 4648 标准示例(1~6 字节,覆盖 `==` / `=` / 无填充三种模式)、边界字节(0 / 255 / NUL 不被截断)、字符集 `+/3+`、较长输入、round-trip 一致性、类型错误 + +### Why +[0080](0080.md) 已把 decode 下沉到 native,性能瓶颈随之转移到 encode 路径(large(10KB) 单次约 220ms,详见 [0080](0080.md) 性能对比表)。在动手下沉 encode 之前,先按 TDD 思路固定语义契约,避免下沉过程中破坏现有行为。`bytevector-base64-encode` 当前实现(`goldfish/liii/base64.scm` 第 18~62 行)使用 `BYTE2BASE64_BV` 查表,输出是 bytevector 而非 string,因此期望值统一用 `string->utf8` 包装,与 decode 测试文件保持对称。 + +### How +- 测试结构与 `bytevector-base64-decode-test.scm` 完全对称,便于阅读和维护 +- round-trip 部分直接复用已下沉到 native 的 `bytevector-base64-decode`,两端互为交叉校验 +- 类型错误用 `check-catch 'type-error`,覆盖 string / 整数 / symbol 三种典型非 bytevector 输入 + +## 后续任务(暂不在本 PR 完成) +- 把 `bytevector-base64-encode` 下沉到 native C++,进一步压低 large(10KB) 的 220ms 量级(与 [0080](0080.md) decode 下沉思路一致) diff --git a/tests/liii/base64/bytevector-base64-encode-test.scm b/tests/liii/base64/bytevector-base64-encode-test.scm new file mode 100644 index 00000000..930cef9c --- /dev/null +++ b/tests/liii/base64/bytevector-base64-encode-test.scm @@ -0,0 +1,92 @@ +(import (liii base64) (liii check)) + +(check-set-mode! 'report-failed) + +;; bytevector-base64-encode +;; 将原始字节向量编码为 Base64 字节向量。 +;; +;; 语法 +;; ---- +;; (bytevector-base64-encode bv) +;; +;; 参数 +;; ---- +;; bv : bytevector +;; 要编码的原始字节序列。 +;; +;; 返回值 +;; ---- +;; bytevector +;; Base64 编码后的字节向量,遵循 RFC 4648: +;; - 每 3 个字节编码为 4 个字符 +;; - 不足 3 字节时使用 '=' 填充 +;; - 字符集为 A-Z, a-z, 0-9, '+', '/' +;; - 输出长度恒为 4 的倍数 +;; +;; 注意 +;; ---- +;; - 空字节向量编码为空字节向量 +;; - 输出字节值为 ASCII(0~127),不做 UTF-8 转换 +;; +;; 错误处理 +;; ---- +;; - 输入非 bytevector -> type-error + +;; 空输入 +(check (bytevector-base64-encode #u8()) => #u8()) + +;; 标准 RFC 4648 示例(覆盖 1/2/3 字节填充情况) +(check (bytevector-base64-encode #u8(102)) => (string->utf8 "Zg==")) +(check (bytevector-base64-encode #u8(102 111)) => (string->utf8 "Zm8=")) +(check (bytevector-base64-encode #u8(102 111 111)) => (string->utf8 "Zm9v")) +(check (bytevector-base64-encode #u8(102 111 111 98)) + => + (string->utf8 "Zm9vYg==") +) ;check +(check (bytevector-base64-encode #u8(102 111 111 98 97)) + => + (string->utf8 "Zm9vYmE=") +) ;check +(check (bytevector-base64-encode #u8(102 111 111 98 97 114)) + => + (string->utf8 "Zm9vYmFy") +) ;check + +;; 边界字节(覆盖全部填充情况) +(check (bytevector-base64-encode #u8(0)) => (string->utf8 "AA==")) +(check (bytevector-base64-encode #u8(255)) => (string->utf8 "/w==")) +(check (bytevector-base64-encode #u8(0 0)) => (string->utf8 "AAA=")) +(check (bytevector-base64-encode #u8(255 255)) => (string->utf8 "//8=")) +(check (bytevector-base64-encode #u8(0 0 0)) => (string->utf8 "AAAA")) +(check (bytevector-base64-encode #u8(255 255 255)) => (string->utf8 "////")) + +;; 字符集覆盖(+ / 边界) +(check (bytevector-base64-encode #u8(251 253 254)) => (string->utf8 "+/3+")) + +;; 含 NUL 字节(不应被截断) +(check (bytevector-base64-encode #u8(0 0 0)) => (string->utf8 "AAAA")) + +;; 较长输入 +(check (bytevector-base64-encode (string->utf8 "The quick brown fox jumps over the lazy dog.") + ) ;bytevector-base64-encode + => + (string->utf8 "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4=") +) ;check + +;; Round-trip 一致性 +(check (bytevector-base64-decode (bytevector-base64-encode #u8())) => #u8()) +(check (bytevector-base64-decode (bytevector-base64-encode #u8(1 2 3 4 5))) + => + #u8(1 2 3 4 5) +) ;check +(check (bytevector-base64-decode (bytevector-base64-encode #u8(255 0 127 128))) + => + #u8(255 0 127 128) +) ;check + +;; 类型错误 +(check-catch 'type-error (bytevector-base64-encode "foo")) +(check-catch 'type-error (bytevector-base64-encode 123)) +(check-catch 'type-error (bytevector-base64-encode 'sym)) + +(check-report)