Hi I have a function which is doing simple operations in a large file. I ran the profiler and it seems like most the time has been spent in datetime operaitons. See code below:
function batterystatus = freqdataV3( freq, date,FFRExcWindow1, FFRExcWindow2, REDstart, REDend, batpower, batenergy, batinitial , batefficiency)
Energy0 = batenergy * batinitial;
uplimit = 50.015;
lowlimit = 49.985;
statuplimit = 50.5;
statlowlimit = 49.5;
batterystatus(:,7) = freq;
batterystatus(1 ,1) = Energy0;
batterystatus(1, 2) = 0;
batterystatus(1, 3) = 0;
batterystatus(1, 4) = 0;
batterystatus(1, 5) = 0;
batterystatus(1, 6) = 0;
FFRfinishdate = datetime(year(date), month(date), day(date),floor(FFRExcWindow1), rem(FFRExcWindow1, 1) * 60, 0);
FFRstartdate = datetime(year(date), month(date), day(date),floor(FFRExcWindow2), rem(FFRExcWindow2, 1) * 60, 0);
REDstartdate = datetime(year(date), month(date), day(date), floor(REDstart), rem(REDstart, 1) * 60,0);
REDenddate = datetime(year(date), month(date), day(date), floor(REDend), rem(REDend, 1) * 60,0);
for i = 2:numel(freq)
if weekday(date(i)) >= 2 && weekday(date(i)) <= 6 && ge(date(i),FFRfinishdate(i)) && lt(date(i),REDstartdate(i))
if batterystatus(i - 1, 1) >= (batenergy - 1)
batterystatus(i ,1:6 ) = batterystatus(i -1 ,1:6 );
else
(...)
When I run the profiler, it highlights the "if weekday(date(i))..." in RED. The whole function has a few more "if"s below, but they similar to the one above but with different conditions. The profiler shows that almost half the total time is due to datetime.subsref. Is this just to perform datetime operations such as "ge" and "lt"? If so, is there any clever away around it that would save me time to run it?
Thanks in advance.

 채택된 답변

Peter Perkins
Peter Perkins 2017년 11월 21일

0 개 추천

Assuming "date" is a datetime array, a couple things as a starting point:
1) The creation of the FFR and RED arrays looks like they could be cleaned up with something like
dateshift(date,'start','day') + hours(FFRExcWindow1)
but hard to say for sure. This won't speed things up but it will be easier to understand.
2) Your comparisons are doing calendar arithmetic, which is inherently expensive, especially if time zones are involved (can't tell). Don't calculate the weekday twice. Actually, don't use weekday at all, it is an older function intended for datenum inputs. Use day(date,'dayofweek'). Also, use isbetween instead of gt and lt. Actually, it may be that you've used ge and lt because you want a half-open interval. Fair enough.
3) I can't tell for sure but it looks like you are finding events that happened between certain times only on weekdays. It may be faster if you call timeofday on the original datetimes and compare those to the endpoints of your window, converted to hours. Hard to say for sure.
3) I can't say for sure if you can vectorize your entire loop, but you can certainly vectorize those conditions. Calculate, once,
dow = day(date,'dayofweek');
tod = timeofday(date);
isWeekdayInWindow = (2 <= dow & dow <= 6) & (FFRExcWindow2 <= tid & tod < REDstart)
Or something like that. Then use that logical to replace the entire condition in your if statement. If you can vectorize the entire loop, even better.

댓글 수: 1

Hi Peter,
I vectorized all my conditions and this helped a lot! I can now run the code through 10m lines in 25 seconds.
Thanks!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Dates and Time에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by