Author vstinner
Recipients vstinner
Date 2020-05-28.00:06:57
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1590624418.05.0.296780868092.issue40799@roundup.psfhosted.org>
In-reply-to
Content
Currently, "import datetime" starts by importing time, math, sys and operator modules, and then execute 2500 lines of Python code, define 7 classes, etc. For what? Just to remove all classes, functions, etc. to replace them with symbols from _decimal module:
---
try:
    from _datetime import *
except ImportError:
    pass
else:
    # Clean up unused names
    del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y,
         _DI4Y, _EPOCH, _MAXORDINAL, _MONTHNAMES, _build_struct_time,
         _check_date_fields, _check_time_fields,
         _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror,
         _date_class, _days_before_month, _days_before_year, _days_in_month,
         _format_time, _format_offset, _index, _is_leap, _isoweek1monday, _math,
         _ord2ymd, _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord,
         _divide_and_round, _parse_isoformat_date, _parse_isoformat_time,
         _parse_hh_mm_ss_ff, _IsoCalendarDate)
    # XXX Since import * above excludes names that start with _,
    # docstring does not get overwritten. In the future, it may be
    # appropriate to maintain a single module level docstring and
    # remove the following line.
    from _datetime import __doc__
---

I would prefer to use the same approach than the decimal module which also has large C and Python implementation. Lib/decimal.py is just:
---
try:
    from _decimal import *
    from _decimal import __doc__
    from _decimal import __version__
    from _decimal import __libmpdec_version__
except ImportError:
    from _pydecimal import *
    from _pydecimal import __doc__
    from _pydecimal import __version__
    from _pydecimal import __libmpdec_version__
---

Advantages:

* Faster import time
* Avoid importing indirectly time, math, sys and operator modules, whereas they are not used

IMO it also better separate the C and the Python implementations.


Attached PR implements this idea.


Currently, "import datetime" imports 4 modules:

  ['_operator', 'encodings.ascii', 'math', 'operator']

With the PR, "import datetime"  imports only 1 module:

  ['encodings.ascii']

Import performance:

  [ref] 814 us +- 32 us -> [change] 189 us +- 4 us: 4.31x faster (-77%)

Measured by:

  env/bin/python -m pyperf timeit -s 'import sys' 'import datetime; del sys.modules["datetime"]; del sys.modules["_datetime"]; del datetime'


Note: I noticed that "import datetime" imports the math module while working on minimizing "import test.support" imports, bpo-40275.
History
Date User Action Args
2020-05-28 00:06:58vstinnersetrecipients: + vstinner
2020-05-28 00:06:58vstinnersetmessageid: <1590624418.05.0.296780868092.issue40799@roundup.psfhosted.org>
2020-05-28 00:06:58vstinnerlinkissue40799 messages
2020-05-28 00:06:57vstinnercreate