如何提高STRREAD()的速度?

时间:2015-09-23 12:06:01

标签: string performance matlab for-loop cell-array

我有一个名为' datetime'的单元格数组。如下格式: 2009.01.01 00:00:02.169

这个' datetime'数组是1819833x1大小,这是大!!! 我想把它分成2个单元格阵列:' date'而且'时间' 日期=' 2009.01.01'和时间=' 00:00:02.169'。

所以我使用for循环如下:

for i=1:numel(datetime)
    [date(i), time(i)] = strread(datetime{i},'%s%s','delimiter',' ');
end

正如您所看到的,它使用循环,并且在处理如此大的数据时速度非常慢。 我今天下午尝试了代码,差不多一个小时过去了,工作还没有完成....

那么有人可以给我一个建议吗? 谢谢!

3 个答案:

答案 0 :(得分:2)

首先,我要预先分配datetime,不要选择哪种解决方案。接下来,我使用以下设置进行了一些实验

s = '2009.01.01 00:00:02.169';
S = repmat({s}, 100000, 1);

结果

使用strread

tic, for i=1:numel(S), [~, ~] = strread(S{i},'%s%s','delimiter',' '); end, toc
Elapsed time is 3.694143 seconds.

使用regexp

tic, for i=1:numel(S), [~] = regexp(S{i},'\s+', 'split'); end, toc
Elapsed time is 1.324754 seconds.

使用cellfun

tic, cellfun(@(x) regexp(x, '\s+', 'split'), S, 'UniformOutput', false); toc
Elapsed time is 2.072437 seconds.

正如您所看到的,大多数方法都很慢。幸运的是,MATLAB中的许多函数都可以直接使用单元格,请注意:

tic, Sresult = regexp(S, '\s+', 'split'); toc
Elapsed time is 0.253819 seconds.

您现在可以通过Sresult{i}{1}Sresult{i}{2}或简单地

来访问结果
date = cellfun(@(x) x{1}, Sresult, 'UniformOutput', false);
time = cellfun(@(x) x{2}, Sresult, 'UniformOutput', false);
Elapsed time is 0.835277 seconds.

超快速方法

我能想到的最快的方法是要求格式始终相同,即每个字符串的长度相等。在你的情况下,我可以想象它是真的。然后你可以使用这样的东西

tic, Sa = cell2mat(S); Sdate = Sa(:,1:10); Stime = Sa(:, 12:end); toc
Elapsed time is 0.060586 seconds.

这里你得到另一个约20的速度因子!

答案 1 :(得分:0)

这是一种方法。不确定它会有多快:

datetime = {'2009.01.01 00:00:02.169'
            '2009.01.02 00:01:05.169'}; %// example data. Cell array of strings
datetime_split = regexp(datetime, '\s+', 'split'); %// split according to spaces
%// Alternatively: datetime_split = cellfun(@strsplit, datetime, 'uniformoutput', 0);
datetime_split = [datetime_split{:}];
date = datetime_split(1:2:end);
time = datetime_split(2:2:end);

根据以上数据,这会产生

>> date
date = 
    '2009.01.01'    '2009.01.02'
>> time
time = 
    '00:00:02.169'    '00:01:05.169'

答案 2 :(得分:0)

所以,谢谢罗伯特......你的建议真有帮助! 首先,我做了预分配,循环+ strread()组合的时间减少到小于40秒我的' datetime'数组大小为1819833x1。

所以这是主要的改进,我们可以看到减少内存重新分配和内存数据复制可以加快这个过程....特别是当你对大量的样本数据执行时。