Skip to content

Avoid Quartz lazyloader from Quartz import * bug #20

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

casebeer
Copy link

I've been having a problem with very long import times/hanging on import.

Specifically,

import pymouse

hangs for in excess of 15 seconds on Mac OS X 10.9.3/Python 2.7.5 with pyobjc v2.5.1.

I've traced the issue back to the pyobjc project, which has a bug discussion containing this message:

If you are only using framework wrappers: make sure you do not use "from Foundation import ", use "import Foundation" or "from Foundation import NSObject" instead. Someone recently noticed that the "from ... import " form is currently much slower than it used to be, due to the way the PyObjC lazy loader is implemented. I'm working on a fix for that, but even with the fix explicit imports will be better because they perform less form (because explicit imports don't have to resolve the symbols you don't use).

https://bitbucket.org/ronaldoussoren/pyobjc/issue/2/faster-metadata-support#comment-5204985

The pymouse/mac.py module uses exactly this from Quartz import * import style.

Changing this to import Quartz and fixing the references to Quartz objects solves the import time issues.

I've also added a unit test that checks the import time for pymouse.

Reproducing the bug

Environment

  • Mac OS X 10.9.3 Mavericks
  • 1.6 GHz Core 2 Duo, 8 GB RAM, SSD
  • Python 2.7.5
  • pyobjc-core 2.5.1
  • PyMouse 1.0 (from PyPi or git b0cc56c)

Steps

  1. import the pymouse module.

You should observe at least a 15 second hang with no output or other response. For example:

print "About to import pymouse"
import pymouse
print "This will print at least 15 seconds later"

Results

Before the patch, at version 1.0/b0cc56c:

$ time python -m pymouse
...
real    0m16.040s
user    0m14.322s
sys 0m0.194s

After changing to import Quartz:

$ time python -m pymouse
...    
real    0m0.558s
user    0m0.390s
sys 0m0.087s

n.b. I've issued substantially this same Pull Request to the PyUserinput project as well.

thektulu and others added 4 commits June 22, 2014 19:02
- Change `from Quartz import *` to the fast `import Quartz`, and update
  all references to Quartz objects to be explicit.
- Add unit test checking import times for pymouse package

pyobjc's lazyloader makes the form `from ... import *` very slow. This
can make importing pymouse extremely slow on OS X due to its use of
from Quartz import *.

See the issue discussion on the pyobjc project:

https://bitbucket.org/ronaldoussoren/pyobjc/issue/2/faster-metadata-support

From that thread on 2013-07-16:

> If you are only using framework wrappers: make sure you do not use "from
> Foundation import ", use "import Foundation" or "from Foundation import
> NSObject" instead. Someone recently noticed that the "from ... import "
> form is currently much slower than it used to be, due to the way the
> PyObjC lazy loader is implemented. I'm working on a fix for that, but
> even with the fix explicit imports will be better because they perform
> less form (because explicit imports don't have to resolve the symbols
> you don't use).

pymouse has this exact problem due to its use of `from Quartz import *`:

    $ time python -m pymouse
    ...
    real	0m16.040s
    user	0m14.322s
    sys	0m0.194s

Changing to just `import Quartz` solves the extremely long hang at
import time problem; after this commit:

    $ time python -m pymouse
    ...
    real	0m0.558s
    user	0m0.390s
    sys	0m0.087s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants