Use bytevector-copy! instead of u8->list, overhead for 400MiB files was reduced from 12 minutes to 7 seconds
1 files changed, 21 insertions(+), 9 deletions(-)

M wispserve/serve.w
M wispserve/serve.w +21 -9
@@ 63,7 63,7 @@ import
     only (ice-9 vlist) alist->vhash vhash-cons vhash-assoc vhash-fold vlist->list vhash-delete
     only (web http) declare-opaque-header!
     only (oop goops) define-generic define-method <string>
-    only (rnrs bytevectors) bytevector-length utf8->string bytevector->u8-list u8-list->bytevector
+    only (rnrs bytevectors) bytevector-length utf8->string bytevector->u8-list u8-list->bytevector bytevector-copy! make-bytevector
     only (srfi srfi-27) random-integer
     only (ice-9 textual-ports) put-string
 

          
@@ 158,6 158,9 @@ define : range-end-< a b
          cdr : range-start-end b
 
 define : merge-ranges received-ranges
+    ;; FIXME: this is currently too slow. First calculate the
+    ;; resulting ranges with source-ranges, then create new
+    ;; bytevectors and fill them without intermediate steps.
     . "merge ranges in RECEIVED-RANGES into a new list, ordered with the range with the highest start first."
     let loop : (merged '()) (original (sort received-ranges range-start->))
         cond

          
@@ 172,12 175,22 @@ define : merge-ranges received-ranges
                   define do : range-data ro
                   define sem : range-start-end rm
                   define seo : range-start-end ro
+                  define new-data
+                    if : string? dm
+                         string-append do dm
+                         make-bytevector ;; declare bytevector
+                             apply +
+                                 map bytevector-length : list do dm
                   define new
                       range : cons (car seo) (cdr sem)
-                              if : string? dm
-                                   string-append do dm
-                                   u8-list->bytevector
-                                       append (bytevector->u8-list do) (bytevector->u8-list dm)
+                            . new-data
+                  when : not : string? dm
+                      ;; fill bytevector
+                      bytevector-copy! do 0 new-data 0
+                          bytevector-length do
+                      bytevector-copy! dm 0 new-data
+                          bytevector-length do
+                          bytevector-length dm
                   loop
                       cons new : cdr merged
                       cdr original

          
@@ 302,7 315,7 @@ define : download-file url
                  missing-ranges-bytes size received-ranges
         ;; pretty-print : list 'received-ranges-start-end : map range-start-end received-ranges
         if : null? missing-ranges
-             range-data : car received-ranges
+             range-data : car : merge-ranges received-ranges
              let*
                  : uri : string->uri-reference url
                    range-to-request : list-ref missing-ranges 0 ;; : random-integer : length missing-ranges

          
@@ 333,9 346,8 @@ define : download-file url
                         let-values : : (start end newsize) : content-range->start-end-size content-range
                             ;; pretty-print : list 'start-end start end
                             loop : if size size newsize
-                                merge-ranges
-                                    cons : range (cons start end) body
-                                         . received-ranges
+                                   cons : range (cons start end) body
+                                        . received-ranges