From 92682779068b3af3768b5ea239895c67e214afcc Mon Sep 17 00:00:00 2001 From: Taavi Burns Date: Sun, 29 Jul 2012 01:15:05 -0400 Subject: [PATCH] Avoid extra calls to calendar.monthrange. daysinmonth isn't used beyond setting cal, which is only used if calendar_end or business_end. Putting the if check in improved performance by a factor of 10. Once all of the flags are false, they can never become true (because of the &= operations), and short-circuiting the rest of the loop in that case saved an additional 20% runtime in the provided example code (see #1686). Much simpler than rewriting in Cython for now. monthrange is relatively expensive and was being called 3x per index datetime when doing a .resample("T"...) operation. Thanks for the help from Erik Welch! --- pandas/tseries/frequencies.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index e64eebc15bed9..198fa142ee2ef 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -800,12 +800,15 @@ def month_position_check(self): if business_start: business_start &= d == 1 or (d <= 3 and wd == 0) - _, daysinmonth = monthrange(y, m) - cal = d == daysinmonth - if calendar_end: - calendar_end &= cal - if business_end: - business_end &= cal or (daysinmonth - d < 3 and wd == 4) + if calendar_end or business_end: + _, daysinmonth = monthrange(y, m) + cal = d == daysinmonth + if calendar_end: + calendar_end &= cal + if business_end: + business_end &= cal or (daysinmonth - d < 3 and wd == 4) + elif not calendar_start and not business_start: + break if calendar_end: return 'ce'