Async imports to reduce startup times

Sorry if this is getting a little sidetracked but this is actually one of the specific things I did want to change with my lazy importer, by coupling the potential import with use of the object/module being imported. The import will just happen the first time the attribute is accessed.

The idea is that if you have a function where some - but not all - branches may end up using a module with a large import time, the import only occurs if those specific branches are hit, without needing to put the import statement inside each branch in order to do so.

Say you have a function that’s something like this:

import big_module

def function_that_might_do_expensive_stuff():
    if condition:
        return "didn't use big_module"
    elif other_condition:
        return big_module.expensive_function(...)
    elif yet_other_condition:
        if sub_condition:
            return big_module.other_expensive_function(...)
        else:
            return "didn't use big_module"
    else:
        return big_module.expensive_function(...)

With the way things are your ‘best’ case would need to look like this, only doing the work of importing the large module when it’s actually needed:

def function_that_might_do_expensive_stuff():
    if condition:
        return "didn't use big_module"
    elif other_condition:
        import big_module
        return big_module.expensive_function(...)
    elif yet_other_condition:
        if sub_condition:
            import big_module
            return big_module.other_expensive_function(...)
        else:
            return "didn't use big_module"
    else:
        import big_module
        return big_module.expensive_function(...)

But I think to avoid the repetitive nature of this people are likely to at best put the import at the top of the function or even the module, and so end up doing the unnecessary import work even when not using the module.


Yes this can be quite noticeable:

Benchmark 1: DUCKTOOLS_EAGER_IMPORT=False ducktools-env --version
  Time (mean ± σ):      33.6 ms ±   2.5 ms    [User: 27.9 ms, System: 5.8 ms]
  Range (min … max):    29.9 ms …  38.7 ms    20 runs
 
Benchmark 2: DUCKTOOLS_EAGER_IMPORT=True ducktools-env --version
  Time (mean ± σ):     135.2 ms ±   3.1 ms    [User: 120.0 ms, System: 15.0 ms]
  Range (min … max):   131.2 ms … 142.3 ms    20 runs
 
Summary
  'DUCKTOOLS_EAGER_IMPORT=False ducktools-env --version' ran
    4.02 ± 0.31 times faster than 'DUCKTOOLS_EAGER_IMPORT=True ducktools-env --version'
1 Like