]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
buffer.cc: short-circuit in copy_out for small lengths
authorPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Thu, 16 Jul 2015 08:18:54 +0000 (10:18 +0200)
committerPiotr Dałek <piotr.dalek@ts.fujitsu.com>
Tue, 4 Aug 2015 07:56:32 +0000 (09:56 +0200)
For small lengths (1, 2, 4 and 8 bytes) use shorter code paths, this
increases performance of function by around 40%.

Signed-off-by: Piotr Dałek <piotr.dalek@ts.fujitsu.com>
src/common/buffer.cc
src/include/buffer.h

index 294f9fc1bbaf3944233b2228b16e5f228d2c3019..90756d36364e5f8b0f9b06510f0c3a6e6650c0e8 100644 (file)
@@ -781,6 +781,38 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   unsigned buffer::ptr::raw_length() const { assert(_raw); return _raw->len; }
   int buffer::ptr::raw_nref() const { assert(_raw); return _raw->nref.read(); }
 
+  void buffer::ptr::copy_out(unsigned o, unsigned l, char *dest) const {
+    assert(_raw);
+    if (o+l > _len)
+        throw end_of_buffer();
+    char* src =  _raw->data + _off + o;
+    if (l > 8) {
+        memcpy(dest, src, l);
+        return;
+    }
+    switch (l) {
+        case 8:
+            *((uint64_t*)(dest)) = *((uint64_t*)(src));
+            return;
+        case 4:
+            *((uint32_t*)(dest)) = *((uint32_t*)(src));
+            return;
+        case 3:
+            *((uint16_t*)(dest)) = *((uint16_t*)(src));
+            *((uint8_t*)(dest+2)) = *((uint8_t*)(src+2));
+            return;
+        case 2:
+            *((uint16_t*)(dest)) = *((uint16_t*)(src));
+            return;
+        case 1:
+            *((uint8_t*)(dest)) = *((uint8_t*)(src));
+            return;
+        default:
+            memcpy(dest, src, l);
+            return;
+        }
+    }
+
   unsigned buffer::ptr::wasted()
   {
     assert(_raw);
index 3ff04063783ae22ccd19299542f0dccf41f316d7..70f00180b0c1e3924395f560b28de25d132ac719 100644 (file)
@@ -219,12 +219,7 @@ public:
     unsigned raw_length() const;
     int raw_nref() const;
 
-    void copy_out(unsigned o, unsigned l, char *dest) const {
-      assert(_raw);
-      if (!((o <= _len) && (o+l <= _len)))
-       throw end_of_buffer();
-      memcpy(dest, c_str()+o, l);
-    }
+    void copy_out(unsigned o, unsigned l, char *dest) const;
 
     bool can_zero_copy() const;
     int zero_copy_to_fd(int fd, int64_t *offset) const;