[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;
- Significant speed-up of datevec,
Daniel J Sebald <=