-
Notifications
You must be signed in to change notification settings - Fork 44
Ubelt Import Time
Ubelt strives to be an non-intrusive lightweight package. It should be easy to use ubelt from bash scripts (i.e. via python -c import ubelt: ubelt...
).
This means that low import time is important. As such, we've spent time optimizing how long it takes to import ubelt. The script in dev/bench/bench_import_time.py
benchmarks the import time over each tagged version of ubelt in it's git history.
As of 1.0.1
(and in development of 1.1.0
) the graph looks like this:
This benchmark was run on an Intel i9 11900k with Python 3.9.9. You can see there is a clear drop in import time in version 0.9.4
where import time was optimized.
On this machine, the current (1.1.0) cumulative import time is roughly 12,279 microseconds (i.e. 12 milliseconds or 0.012 seconds) using the command python -X importtime -c "import ubelt"
.
The breakdown is as follows:
import time: self [us] | cumulative | imported package
import time: 135 | 135 | _io
import time: 23 | 23 | marshal
import time: 190 | 190 | posix
import time: 322 | 669 | _frozen_importlib_external
import time: 53 | 53 | time
import time: 160 | 212 | zipimport
import time: 35 | 35 | _codecs
import time: 283 | 317 | codecs
import time: 228 | 228 | encodings.aliases
import time: 340 | 884 | encodings
import time: 120 | 120 | encodings.utf_8
import time: 100 | 100 | _signal
import time: 133 | 133 | encodings.latin_1
import time: 26 | 26 | _abc
import time: 140 | 166 | abc
import time: 148 | 314 | io
import time: 77 | 77 | _stat
import time: 152 | 228 | stat
import time: 604 | 604 | _collections_abc
import time: 84 | 84 | genericpath
import time: 126 | 210 | posixpath
import time: 313 | 1354 | os
import time: 105 | 105 | _sitebuiltins
import time: 41 | 41 | _locale
import time: 78 | 118 | _bootlocale
import time: 149 | 149 | types
import time: 196 | 196 | warnings
import time: 93 | 289 | importlib
import time: 78 | 78 | importlib.machinery
import time: 184 | 184 | _heapq
import time: 108 | 291 | heapq
import time: 332 | 332 | itertools
import time: 79 | 79 | keyword
import time: 41 | 41 | _operator
import time: 154 | 195 | operator
import time: 102 | 102 | reprlib
import time: 39 | 39 | _collections
import time: 560 | 1595 | collections
import time: 96 | 96 | collections.abc
import time: 27 | 27 | _functools
import time: 283 | 310 | functools
import time: 271 | 580 | contextlib
import time: 462 | 462 | enum
import time: 40 | 40 | _sre
import time: 205 | 205 | sre_constants
import time: 193 | 397 | sre_parse
import time: 156 | 593 | sre_compile
import time: 91 | 91 | copyreg
import time: 321 | 1466 | re
import time: 1089 | 4824 | typing
import time: 312 | 5213 | importlib.abc
import time: 172 | 5673 | importlib.util
import time: 795 | 795 | sitecustomize
import time: 11293 | 19484 | site
import time: 201 | 201 | ubelt.orderedset
import time: 164 | 164 | ubelt.progiter
import time: 141 | 141 | ubelt.util_const
import time: 82 | 222 | ubelt.util_arg
import time: 142 | 142 | ubelt.util_cache
import time: 121 | 121 | select
import time: 98 | 219 | ubelt.util_cmd
import time: 77 | 77 | ubelt.util_colors
import time: 129 | 129 | math
import time: 133 | 262 | ubelt.util_list
import time: 154 | 415 | ubelt.util_dict
import time: 90 | 90 | ubelt.util_download
import time: 78 | 78 | ubelt.util_download_manager
import time: 190 | 190 | ubelt.util_format
import time: 71 | 71 | ubelt.util_func
import time: 73 | 73 | concurrent
import time: 98 | 98 | token
import time: 555 | 652 | tokenize
import time: 85 | 736 | linecache
import time: 155 | 891 | traceback
import time: 125 | 125 | _weakrefset
import time: 297 | 421 | weakref
import time: 24 | 24 | _string
import time: 482 | 505 | string
import time: 453 | 453 | threading
import time: 27 | 27 | atexit
import time: 1349 | 3644 | logging
import time: 336 | 3979 | concurrent.futures._base
import time: 108 | 4159 | concurrent.futures
import time: 121 | 4280 | ubelt.util_futures
import time: 433 | 433 | _hashlib
import time: 102 | 102 | _blake2
import time: 139 | 673 | hashlib
import time: 189 | 861 | ubelt.util_hash
import time: 129 | 129 | ubelt.util_import
import time: 112 | 112 | ubelt.util_indexable
import time: 95 | 95 | ubelt.util_io
import time: 87 | 87 | ubelt.util_platform
import time: 95 | 182 | ubelt.util_links
import time: 88 | 88 | ubelt.util_memoize
import time: 78 | 78 | ubelt.util_mixins
import time: 102 | 102 | fnmatch
import time: 209 | 209 | nt
import time: 194 | 194 | nt
import time: 196 | 196 | nt
import time: 268 | 268 | nt
import time: 150 | 1014 | ntpath
import time: 35 | 35 | errno
import time: 81 | 81 | urllib
import time: 597 | 677 | urllib.parse
import time: 461 | 2287 | pathlib
import time: 567 | 2854 | ubelt.util_path
import time: 94 | 94 | ubelt.util_str
import time: 164 | 164 | ubelt.util_stream
import time: 86 | 86 | ubelt.util_time
import time: 105 | 105 | ubelt.util_zip
import time: 423 | 11407 | ubelt
Currently the main time sinks are due to needing to import concurrent.futures
(due to the logging module) and pathlib
on the top level (for inheritance purposes). In the future when ubelt is Python > 3.7 only, we may move to a lazy import solution, which will make import time effectively zero.