[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Speed up 'unique'
From: |
Daniel J Sebald |
Subject: |
Speed up 'unique' |
Date: |
Wed, 17 Dec 2008 04:52:43 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20041020 |
Attached is a patch that tweaks unique.m to cut the time of the
following test by 4:
function testfunc3(m, varargin)
x = [[1:20] [20:-1:1]];
tstart = cputime();
for i=1:5000
[y i j] = unique(x);
end
cputime() - tstart
end
The reason for the improvement is that all the testing for the options
is avoided if no options are present. (I.e., avoids three calls to
'strmatch' and a couple conditionals.) Also, 'prepad' really isn't a
necessary call, as I see it.
If one looks closely at the handling of options, I added a recursive
call to make sure the options are unique. Otherwise, something like
this fails:
unique([1:10], 'first', 'first')
The recursion looks funny, but because of the added check on the number
of arguments, it is not an indefinite loop.
Dan
--- unique.m.orig 2008-12-17 03:08:02.000000000 -0600
+++ unique.m 2008-12-17 04:45:08.590020461 -0600
@@ -45,26 +45,31 @@
print_usage ();
endif
- ## parse options
- if (iscellstr (varargin))
- optfirst = strmatch ('first', varargin) > 0;
- optlast = strmatch ('last', varargin) > 0;
- optrows = strmatch ('rows', varargin) > 0 && size (x, 2) > 1;
- if (optfirst && optlast)
- error ("unique: cannot specify both 'last' and 'first'.");
- elseif (optfirst + optlast + optrows != nargin-1)
- error ("unique: invalid option.");
+ if (nargin > 1)
+
+ ## parse options
+ if (iscellstr (varargin))
+ varargin = unique(varargin);
+ optfirst = strmatch ('first', varargin) > 0;
+ optlast = strmatch ('last', varargin) > 0;
+ optrows = strmatch ('rows', varargin) > 0 && size (x, 2) > 1;
+ if (optfirst && optlast)
+ error ("unique: cannot specify both 'last' and 'first'.");
+ elseif (optfirst + optlast + optrows != nargin-1)
+ error ("unique: invalid option.");
+ endif
+ else
+ error ("unique: options must be strings");
endif
- optlast = ! optfirst;
- else
- error ("unique: options must be strings");
- endif
- if (iscell (x))
- if (optrows)
+ if (optrows && iscell (x))
warning ("unique: 'rows' is ignored for cell arrays");
optrows = false;
endif
+
+ else
+ optfirst = 0;
+ optrows = 0;
endif
if (optrows)
@@ -101,12 +106,11 @@
y(idx) = [];
endif
- ## I don't know why anyone would need reverse indices, but it
- ## was an interesting challenge. I welcome cleaner solutions.
if (nargout >= 3)
j = i;
- j(i) = cumsum (prepad (! match, n, 1));
+ j(i) = cumsum ([1 !match]);
endif
+
if (optfirst)
i(idx+1) = [];
else