[geany/geany] cbc85b: Improve memory backend of mio_read()

Colomban Wendling git-noreply at xxxxx
Sat Oct 24 18:15:58 UTC 2015


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Sat, 24 Oct 2015 18:15:58 UTC
Commit:      cbc85b7444da9e5210f1a7ac18a1e223af784af9
             https://github.com/geany/geany/commit/cbc85b7444da9e5210f1a7ac18a1e223af784af9

Log Message:
-----------
Improve memory backend of mio_read()

Drop the loop in mem_read() in favor of a single memcpy() call.

This greatly improves performances when nmemb > 1, for a small loss
for some values of size when nmemb == 1.  Gain can theoretically be
infinite since swapping nmemb and size parameters changes almost
nothing while it had a dramatic performance impact previously.  Loss
is up to about 25% in the worst case for some values of size when
nmemb is 1.

Also, now the function always copies as much data as possible, not only
whole blocks.  This follows the glibc implementation of fread() and
simplifies the code.  Doing so also fixes the position after a partial
read to be at the last readable character rather than the end of the
last read block.


Modified Paths:
--------------
    tagmanager/mio/mio-memory.c

Modified: tagmanager/mio/mio-memory.c
40 lines changed, 20 insertions(+), 20 deletions(-)
===================================================================
@@ -73,34 +73,34 @@ mem_free (MIO *mio)
 
 static gsize
 mem_read (MIO    *mio,
-          void   *ptr,
+          void   *ptr_,
           gsize   size,
           gsize   nmemb)
 {
   gsize n_read = 0;
   
   if (size != 0 && nmemb != 0) {
-    if (mio->impl.mem.ungetch != EOF) {
-      *((guchar *)ptr) = (guchar)mio->impl.mem.ungetch;
-      mio->impl.mem.ungetch = EOF;
-      mio->impl.mem.pos++;
-      if (size == 1) {
-        n_read++;
-      } else if (mio->impl.mem.pos + (size - 1) <= mio->impl.mem.size) {
-        memcpy (&(((guchar *)ptr)[1]),
-                &mio->impl.mem.buf[mio->impl.mem.pos], size - 1);
-        mio->impl.mem.pos += size - 1;
-        n_read++;
-      }
+    gsize   size_avail  = mio->impl.mem.size - mio->impl.mem.pos;
+    gsize   copy_bytes  = size * nmemb;
+    guchar *ptr         = ptr_;
+    
+    if (size_avail < copy_bytes) {
+      copy_bytes = size_avail;
     }
-    for (; n_read < nmemb; n_read++) {
-      if (mio->impl.mem.pos + size > mio->impl.mem.size) {
-        break;
-      } else {
-        memcpy (&(((guchar *)ptr)[n_read * size]),
-                &mio->impl.mem.buf[mio->impl.mem.pos], size);
-        mio->impl.mem.pos += size;
+    
+    if (copy_bytes > 0) {
+      n_read = copy_bytes / size;
+      
+      if (mio->impl.mem.ungetch != EOF) {
+        *ptr = (guchar) mio->impl.mem.ungetch;
+        mio->impl.mem.ungetch = EOF;
+        copy_bytes--;
+        mio->impl.mem.pos++;
+        ptr++;
       }
+      
+      memcpy (ptr, &mio->impl.mem.buf[mio->impl.mem.pos], copy_bytes);
+      mio->impl.mem.pos += copy_bytes;
     }
     if (mio->impl.mem.pos >= mio->impl.mem.size) {
       mio->impl.mem.eof = TRUE;



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list