Skip to content

PERF: 30% faster is_period_object checks #33961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions pandas/_libs/lib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ from pandas._libs.tslibs.nattype cimport (
from pandas._libs.tslibs.conversion cimport convert_to_tsobject
from pandas._libs.tslibs.timedeltas cimport convert_to_timedelta64
from pandas._libs.tslibs.timezones cimport get_timezone, tz_compare
from pandas._libs.tslibs.period cimport is_period_object

from pandas._libs.missing cimport (
checknull,
Expand Down Expand Up @@ -185,7 +186,7 @@ def is_scalar(val: object) -> bool:

# Note: PyNumber_Check check includes Decimal, Fraction, numbers.Number
return (PyNumber_Check(val)
or util.is_period_object(val)
or is_period_object(val)
or is_interval(val)
or util.is_offset_object(val))

Expand Down Expand Up @@ -942,7 +943,7 @@ def is_period(val: object) -> bool:
-------
bool
"""
return util.is_period_object(val)
return is_period_object(val)


def is_list_like(obj: object, allow_sets: bool = True) -> bool:
Expand Down Expand Up @@ -1417,7 +1418,7 @@ def infer_dtype(value: object, skipna: bool = True) -> str:
if is_bytes_array(values, skipna=skipna):
return "bytes"

elif util.is_period_object(val):
elif is_period_object(val):
if is_period_array(values):
return "period"

Expand Down Expand Up @@ -1849,7 +1850,7 @@ cpdef bint is_time_array(ndarray values, bint skipna=False):

cdef class PeriodValidator(TemporalValidator):
cdef inline bint is_value_typed(self, object value) except -1:
return util.is_period_object(value)
return is_period_object(value)

cdef inline bint is_valid_null(self, object value) except -1:
return checknull_with_nat(value)
Expand Down
1 change: 1 addition & 0 deletions pandas/_libs/tslibs/period.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cdef bint is_period_object(object obj)
10 changes: 9 additions & 1 deletion pandas/_libs/tslibs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ cdef extern from "src/datetime/np_datetime.h":
npy_datetimestruct *d) nogil

cimport pandas._libs.tslibs.util as util
from pandas._libs.tslibs.util cimport is_period_object

from pandas._libs.tslibs.timestamps import Timestamp
from pandas._libs.tslibs.timezones cimport is_utc, is_tzlocal, get_dst_info
Expand Down Expand Up @@ -2467,6 +2466,15 @@ class Period(_Period):
return cls._from_ordinal(ordinal, freq)


cdef bint is_period_object(object obj):
"""
Cython-optimized equivalent of isinstance(obj, Period)
"""
# Note: this is significantly faster than the implementation in tslibs.util,
# only use the util version when necessary to prevent circular imports.
return isinstance(obj, _Period)


cdef int64_t _ordinal_from_fields(int year, int month, quarter, int day,
int hour, int minute, int second, freq):
base, mult = get_freq_code(freq)
Expand Down