octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Significant speed-up of datevec


From: Daniel J Sebald
Subject: Significant speed-up of datevec
Date: Wed, 17 Dec 2008 22:33:08 -0600
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20041020

Attached is a patch to significantly speed up datevec() in the case that a 
string matrix or string cell is passed in.  The ~50 speedup comes simply from 
only deciphering the format string once instead of for every entry in the 
cell/string matrix.  Here is a test function:

function DN = testfunc4()
 date1 = '2008-12-16 22:12:00';
 D = repmat(date1, 1000, 1);
 tstart = cputime();
 DN = datenum(D, 'yyyy-mm-dd HH:MM:SS');
 cputime - tstart
end

and results, without the patch:

octave:1> DN = testfunc4();
ans =  70.594

with the patch:

octave:1> DN = testfunc4();
ans =  1.4648

There are probably other little things that could be done to save some time, 
but this gets the bulk of it.

What I don't understand though, is that successively calling this test function 
results in worse performance after the first call:

octave:2> DN = testfunc4();
ans =  2.1877
octave:3> DN = testfunc4();
ans =  2.2437
...

Any ideas?  (I check the usual suspects, like having to delete the return 
value, etc.)

Dan
--- datevec.m.orig      2008-12-10 02:35:30.000000000 -0600
+++ datevec.m   2008-12-17 22:09:53.784096244 -0600
@@ -108,9 +108,7 @@
   endif
 
   if (ischar (date))
-    t = date;
-    date = cell (1);
-    date{1} = t;
+    date = cellstr (date);
   endif
 
   if (iscell (date))
@@ -123,7 +121,8 @@
       for k = 1:nd
         found = false;
         for l = 1:nfmt
-          [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, 
std_formats{l}, p);
+          [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ 
(std_formats{l});
+          [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, 
p, f, rY, ry, fy, fm, fd, fh, fmi, fs);
           if (found)
             break;
           endif
@@ -133,8 +132,10 @@
         endif
       endfor
     else
+      % Decipher the format string just once for sake of speed.
+      [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ (f);
       for k = 1:nd
-        [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, f, 
p);
+        [found y(k) m(k) d(k) h(k) mi(k) s(k)] = __date_str2vec__ (date{k}, p, 
f, rY, ry, fy, fm, fd, fh, fmi, fs);
         if (! found)
           error ("datevec: date not parsed correctly with given format");
         endif
@@ -183,7 +184,7 @@
 
 ### endfunction
 
-function [found, y, m, d, h, mi, s] = __date_str2vec__ (ds, f, p)
+function [f, rY, ry, fy, fm, fd, fh, fmi, fs] = __date_vfmt2sfmt__ (f)
 
   # Play safe with percent signs
   f = strrep(f, "%", "%%");
@@ -245,14 +246,28 @@
   f = strrep (f, "MM", "%M");
   f = strrep (f, "SS", "%S");
 
+  rY = rindex (f, "%Y");
+  ry = rindex (f, "%y");
+
+  # check whether we need to give default values
+  # possible error when string contains "%%"
+  fy = rY || ry;
+  fm = index (f, "%m") || index (f, "%b") || index (f, "%B");
+  fd = index (f, "%d") || index (f, "%a") || index (f, "%A");
+  fh = index (f, "%H") || index (f, "%I");
+  fmi = index (f, "%M");
+  fs = index (f, "%S");
+
+### endfunction
+
+function [found, y, m, d, h, mi, s] = __date_str2vec__ (ds, p, f, rY, ry, fy, 
fm, fd, fh, fmi, fs)
+
   [tm, nc] = strptime (ds, f);
 
-  if (nc == length (ds) + 1)
+  if (nc == size (ds, 2) + 1)
     y = tm.year + 1900; m = tm.mon + 1; d = tm.mday;
     h = tm.hour; mi = tm.min; s = tm.sec + tm.usec / 1e6;
     found = true;
-    rY = rindex (f, "%Y");
-    ry = rindex (f, "%y");
     if (rY < ry)
       if (y > 1999)
         y -= 2000;
@@ -264,14 +279,6 @@
         y += 100;
       endif
     endif
-    # check whether we need to give default values
-    # possible error when string contains "%%"
-    fy = rY || ry;
-    fm = index (f, "%m") || index (f, "%b") || index (f, "%B");
-    fd = index (f, "%d") || index (f, "%a") || index (f, "%A");
-    fh = index (f, "%H") || index (f, "%I");
-    fmi = index (f, "%M");
-    fs = index (f, "%S");
     if (! fy && ! fm && ! fd)
       tvm = localtime (time ());  ## tvm: this very moment
       y = tvm.year + 1900;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]