日別アーカイブ: 2024/08/18

PyObjC がトンデモなく遅い

今日は久しぶりに PyObjC で小物を作ろうとした。
いやまあ macOS プログラミングは完全に放置気味でしたね。
ということでまずアップグレードを行なってと。

# pip Upgrade
pip3 install --upgrade pip

# PyObjC Install or Upgrade
pip3 install -U pyobjc

で本題、PyObjC コードの初期化がありえないほど遅い。
NSWindow を作ったら表示されるまで十秒くらい待たされる。
Python 標準モジュールのみのコードなら普通に一瞬だ。
しばらく色々試したらこういうことだった。

#!/usr/bin/env python3

'''
    app.old.py
'''

import time
start = time.time()

from AppKit import *
import objc

class AppMenu(NSMenu):
    def init(self):
        objc.super(AppMenu, self).init()
        item_app  = NSMenuItem.new()
        self.addItem_(item_app)
        menu_app = NSMenu.new()
        item_app.setSubmenu_(menu_app)
        # command+Q で閉じるメニュー
        item_quit = NSMenuItem.new()
        item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q')
        menu_app.addItem_(item_quit)
        return self

# NSApp を作る
NSApplication.sharedApplication()
# command+Q で終了するメニューを入れる
NSApp.setMainMenu_(AppMenu.new())
# コレをしないと最前面に出てこない
NSApp.activateIgnoringOtherApps_(True)
# メインループを回さない
#NSApp.run()

# 経過時間 ms
print(f'{time.time() - start} ms')

from を使う今までやっていたコード。

#!/usr/bin/env python3

'''
    aoo.new.py
'''

import time
start = time.time()

import AppKit, objc

class AppMenu(AppKit.NSMenu):
    def init(self):
        objc.super(AppMenu, self).init()
        item_app  = AppKit.NSMenuItem.new()
        self.addItem_(item_app)
        menu_app = AppKit.NSMenu.new()
        item_app.setSubmenu_(menu_app)
        # command+Q で閉じるメニュー
        item_quit = AppKit.NSMenuItem.new()
        item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q')
        menu_app.addItem_(item_quit)
        return self

# NSApp を作る
AppKit.NSApplication.sharedApplication()
# command+Q で終了するメニューを入れる
AppKit.NSApp.setMainMenu_(AppMenu.new())
# コレをしないと最前面に出てこない
AppKit.NSApp.activateIgnoringOtherApps_(True)
# メインループを回さないさない
#AppKit.NSApp.run()

# 経過時間 ms
print(f'{time.time() - start} ms')

都度プリフィクスを書く面倒くさいコード。

PyObjC

from で * を使うとトンデモネェ遅さになってしまった。
以前は from でも同じような速度で初期化されていたんですが。
NSApp だけでコレ、NSWindow まで作るとすげぇ悲惨。

Python 3.11 からの高速化の弊害なのかな。
from は全部辿ってキャッシュとかになっていたらまあこうなるよな。
いや PyObjC 側の不具合かもしれないけどプリフィクス化で解決するし。
Cocoa のメソッド名長いんだよな、GTK+ みたくできないのかと。
アスタリスクを使っている人は調べてみたほうがいいかも。

ついでに、objc は import しなくてもよかったのに必須になった。
activateIgnoringOtherApps が動作しない、何故?
ちょっと放置しすぎたな、もう少し調べよう。
秋の渡り鳥が来る前にやらないとまた放置しそうだし。