]> asedeno.scripts.mit.edu Git - cl-protobufs.git/commitdiff
Speed up string (de)serialization a bit
authorScott McKay <swm@google.com>
Wed, 2 May 2012 16:02:57 +0000 (16:02 +0000)
committerScott McKay <swm@google.com>
Wed, 2 May 2012 16:02:57 +0000 (16:02 +0000)
git-svn-id: http://svn.internal.itasoftware.com/svn/ita/trunk/qres/lisp/quux/protobufs@542000 f8382938-511b-0410-9cdd-bb47b084005c

proto-pkgdcl.lisp
wire-format.lisp

index 757f77acdd128e20bc491c27fa6d554a2a7ea777..e1c40a5ddbb0a3a1bebed36ca9fa9b4432b10f4a 100644 (file)
    "ENCODE-FIXED64"
    "ENCODE-SINGLE"
    "ENCODE-DOUBLE"
+   "ENCODE-STRING"
    "ENCODE-OCTETS"
    "ZIG-ZAG-ENCODE32"
    "ZIG-ZAG-ENCODE64"
    "DECODE-FIXED64"
    "DECODE-SINGLE"
    "DECODE-DOUBLE"
+   "DECODE-STRING"
    "DECODE-OCTETS"
    "ZIG-ZAG-DECODE32"
    "ZIG-ZAG-DECODE64"
index c0914de0e2d3d3adccbf44ac871e792e6a34a0b1..d58bded5d775cdca02b86d02175881beff895eca 100644 (file)
         ((:sfixed64)
          (encode-sfixed64 val buffer idx))
         ((:string)
-         (encode-octets (babel:string-to-octets val :encoding :utf-8) buffer idx))
+         (encode-string val buffer idx))
         ((:bytes)
          (encode-octets val buffer idx))
         ((:bool)
                       (string val)
                       ;; Non-keyword symbols are consy, avoid them if possible
                       (format nil "~A:~A" (package-name (symbol-package val)) (symbol-name val)))))
-           (encode-octets (babel:string-to-octets val :encoding :utf-8) buffer idx)))
+           (encode-string val buffer idx)))
         ((:date :time :datetime :timestamp)
          (encode-uint64 val buffer idx))))))
 
             ((:sfixed64)
              `(encode-sfixed64 ,val ,buffer idx))
             ((:string)
-             `(encode-octets (babel:string-to-octets ,val :encoding :utf-8) ,buffer idx))
+             `(encode-string ,val ,buffer idx))
             ((:bytes)
              `(encode-octets ,val ,buffer idx))
             ((:bool)
       ((:sfixed64)
        (decode-sfixed64 buffer index))
       ((:string)
-       (multiple-value-bind (val idx)
-           (decode-octets buffer index)
-         (values (babel:octets-to-string val :encoding :utf-8) idx)))
+       (decode-string buffer index))
       ((:bytes)
        (decode-octets buffer index))
       ((:bool)
       ((:symbol)
        ;; Note that this is consy, avoid it if possible
        (multiple-value-bind (val idx)
-           (decode-octets buffer index)
-         (let ((val (babel:octets-to-string val :encoding :utf-8)))
-           (values (make-lisp-symbol val) idx))))
+           (decode-string buffer index)
+         (values (make-lisp-symbol val) idx)))
       ((:date :time :datetime :timestamp)
        (decode-uint64 buffer index)))))
 
           ((:sfixed64)
            `(decode-sfixed64 ,buffer ,index))
           ((:string)
-           `(multiple-value-bind (val idx)
-                (decode-octets ,buffer ,index)
-              (values (babel:octets-to-string val :encoding :utf-8) idx)))
+           `(decode-string ,buffer ,index))
           ((:bytes)
            `(decode-octets ,buffer ,index))
           ((:bool)
           (iincf index)))))
   (values index buffer))
 
+(defun encode-string (string buffer index)
+  "Encodes the octets into the buffer at the given index.
+   Modifies the buffer, and returns the new index into the buffer.
+   Watch out, this function turns off most type checking and all array bounds checking."
+  (declare (type (simple-array (unsigned-byte 8)) buffer)
+           (type fixnum index))
+  (locally (declare (optimize (speed 3) (safety 0) (debug 0)))
+    (let* ((octets (babel:string-to-octets string :encoding :utf-8))
+           (len (length octets))
+           (idx (encode-uint32 len buffer index)))
+      (declare (type fixnum len)
+               (type (unsigned-byte 32) idx))
+      (replace buffer octets :start1 idx)
+      (values (i+ idx len) buffer))))
+
 (defun encode-octets (octets buffer index)
   "Encodes the octets into the buffer at the given index.
    Modifies the buffer, and returns the new index into the buffer.
         (decf high #.(ash 1 32)))
       (values (make-double-float low high) index))))
 
+(defun decode-string (buffer index)
+  "Decodes the next UTF-8 encoded string in the buffer at the given index.
+   Returns both the decoded string and the new index into the buffer.
+   Watch out, this function turns off most type checking and all array bounds checking."
+  (declare (type (simple-array (unsigned-byte 8)) buffer)
+           (type fixnum index))
+  (locally (declare (optimize (speed 3) (safety 0) (debug 0)))
+    (multiple-value-bind (len idx)
+        (decode-uint32 buffer index)
+      (declare (type (unsigned-byte 32) len)
+               (type fixnum idx))
+      (values (babel:octets-to-string buffer :start idx :end (i+ idx len) :encoding :utf-8) (i+ idx len)))))
+
 (defun decode-octets (buffer index)
   "Decodes the next octets in the buffer at the given index.
    Returns both the decoded value and the new index into the buffer.