Current performance worries
-
Unpacking stdlib is very slow. See "things that look promising" below.
-
There's a somewhat sad trade-off between disk I/O being slow on one hand, and bytecode-compiling PYCs being slow on the other.
Things I tried that look promising:
-
If you put the Python
*.so
modules in the jniLibs directory, then you can add it to PYTHONPATH, ignore PYTHONHOME, and import the libs straight from jnilibs-land. Not bad. -
Therefore I can probably oxidized_importer-ify stdlib's pure-Python parts, and perhaps even add PYCs to that. TBD. I can use
ZipFile
to read the oxidized_importer data straight out of the APK, which would do a copy, but that's OK. -
Switching to checked-hash or unchecked-hash invalidation mode for PYCs looks very, very promising. SOURCE_DATE_EPOCH in the environment during build and runtime is one way to cause that.
Things I tried that didn't work out:
-
If I use zipimport to wrap the stdlib, I think it's really slow when zipimport fails to do an import? Seems odd.
-
Remove
list()
from rubicon-java java/api.py itertools.product() call -- didn't seem to change anything (but I didn't necessarily benchmark well) -
Switch rubicon-java java/api.py to a less exception-heavy idiom -- actually I never really tried this
-
Make stdlib a ZIP file -- this only ever worsened second-launch. Note that you have to do
zipfile.zip/lib/python3.7
to get the stdlib to be findable. -
Using oxidized_importer -- well, I didn't try this for stdlib, it's probably peaceful for stdlib
-
Adding PYCs to stdlib -- I very briefly tested this but didn't record results well
-
Doing less
JavaClass
definition work at import time -- all ofandroid_widgets.py
takes a mere 10ms to import tops, and 10ms is fine. -
Implementing a
getMethod()
method. I half-tried this. My measurement environment is so noisy, but I think that the following (if added to toga'ssrc/android/toga_android/libs/activity.py
) should save 80ms or so. Is that enough to break the abstraction layer? Probably. OnlyTextView
is as painful to deal with; other classes are just fast (approx 1ms). Maybe they don't have as many methods.
# Performance optimization: explicitly get a reference to the
# setPythonApp method for efficiency. This allows us to skip
# rubicon-java's convenient machinery for making Python stubs
# dynamically for Java methods.
def set_python_app(python_app):
java_method = java.GetStaticMethodID(MainActivity.__jni__,
b"setPythonApp", b"(Lorg/beeware/android/IPythonApp;)V")
java.CallStaticVoidMethod(MainActivity.__jni__, java_method, python_app)