更快捷地获取日期范围内的唯一区域列表

时间:2018-04-25 16:54:26

标签: matlab

我正在尝试在日期范围(dateStartdateEnd(日期)中获得唯一季度列表。

对于2014年1月1日到2015年2月2日之间的日期范围,输出应该类似于这样:

201401
201402
201403
201404
201501
201502

目前我执行以下操作(请参阅下面的代码),但处理0.013dateStart = 735173的{​​{1}}秒需要很长时间。我相信这是因为许多低效的规则(转换为字符串然后再转换为双倍)。

还有其他方法,计算效率更高,以获得理想的结果吗?

dateEnd = 735538

1 个答案:

答案 0 :(得分:2)

此功能的表现要好得多:

function dranges = yyyyqq_range_new(dateStart, dateEnd)
    dates    = (dateStart:dateEnd)';
    datesstr = sprintfc('%d0%d',[year(dates) quarter(dates)]);
    dranges  = str2double(unique(datesstr));
end

以下是1000次迭代的小基准:

ds = 735173;
de = 735538;

tic();
for i = 1:1000
    dr = yyyyqq_range(ds,de);
end
toc();

tic();
for i = 1:1000
    dr = yyyyqq_range_new(ds,de);
end
toc();

function dranges = yyyyqq_range(dateStart, dateEnd)
    dates     = (dateStart:dateEnd)';
    datesstr  = cellstr(datestr(dates,'yyyyqq'));
    datesstr  = strrep(datesstr,'Q1','01');
    datesstr  = strrep(datesstr,'Q2','02');
    datesstr  = strrep(datesstr,'Q3','03');
    datesstr  = strrep(datesstr,'Q4','04');
    datesnumb = str2double(datesstr);
    dranges   = unique(datesnumb);  
end

function dranges = yyyyqq_range_new(dateStart, dateEnd)
    dates    = (dateStart:dateEnd)';
    datesstr = sprintfc('%d0%d',[year(dates) quarter(dates)]);
    dranges  = str2double(unique(datesstr));
end

其结果是:

  

经过的时间是16.064419秒。

     

经过的时间是0.836365秒。

基本上,这是我的整体改进:

  1. 我删除了实现quarter函数的字符串替换过程(非常昂贵),该函数输出日期范围的已合规值。
  2. 我使用了未记录的sprintfc函数,而不是使用datestr函数,以便获得更快的数字到字面的日期转换。
  3. 我保留了str2double转换,但我没有将其应用于所有文字日期表示,而是仅将其应用于unique函数输出,因此必须在较小的量上执行字符串。
  4. 我的功能的更快版本可以实现坚持数字类型(实际上,将日期转换为字符串是一个不必要的步骤,因为你想要数字)。这是它:

    function dranges = yyyyqq_range_new_num(dateStart, dateEnd)
        dates   = (dateStart:dateEnd)';
        dranges = unique((year(dates) .* 100) + quarter(dates));
    end
    
    它闪电般快速。在同一个基准测试框架内,它可以在大约0.15秒内完成任务。