From: Scott McKay Date: Wed, 2 May 2012 16:02:57 +0000 (+0000) Subject: Speed up string (de)serialization a bit X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=c7a026fdfcb2d812a66542f21c553edb7b77594d;p=cl-protobufs.git Speed up string (de)serialization a bit git-svn-id: http://svn.internal.itasoftware.com/svn/ita/trunk/qres/lisp/quux/protobufs@542000 f8382938-511b-0410-9cdd-bb47b084005c --- diff --git a/proto-pkgdcl.lisp b/proto-pkgdcl.lisp index 757f77a..e1c40a5 100644 --- a/proto-pkgdcl.lisp +++ b/proto-pkgdcl.lisp @@ -186,6 +186,7 @@ "ENCODE-FIXED64" "ENCODE-SINGLE" "ENCODE-DOUBLE" + "ENCODE-STRING" "ENCODE-OCTETS" "ZIG-ZAG-ENCODE32" "ZIG-ZAG-ENCODE64" @@ -195,6 +196,7 @@ "DECODE-FIXED64" "DECODE-SINGLE" "DECODE-DOUBLE" + "DECODE-STRING" "DECODE-OCTETS" "ZIG-ZAG-DECODE32" "ZIG-ZAG-DECODE64" diff --git a/wire-format.lisp b/wire-format.lisp index c0914de..d58bded 100644 --- a/wire-format.lisp +++ b/wire-format.lisp @@ -139,7 +139,7 @@ ((: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) @@ -154,7 +154,7 @@ (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)))))) @@ -183,7 +183,7 @@ ((: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) @@ -326,9 +326,7 @@ ((: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) @@ -343,9 +341,8 @@ ((: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))))) @@ -376,9 +373,7 @@ ((: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) @@ -724,6 +719,21 @@ (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. @@ -880,6 +890,19 @@ (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.