кликер жрет много процессорного времени - python 3

У меня есть простая программа, которая делает следующее: 1) Пользователь куда-то указывает мышью, 2) затем пользователь нажимает пробел, 3) и компьютер в этот момент выполняет определенное количество щелчков левой кнопкой мыши.

Программа работает нормально, проблема только одна - жрет 30-50% процессорного времени на 4х ядерном процессоре. В чем проблема?

import pyautogui
import ctypes

pyautogui.FAILSAFE = True

def get_space_state():
    hllDll = ctypes.WinDLL ("User32.dll")
    VK_SPACE = 0x20
    return hllDll.GetKeyState(VK_SPACE)

while True:
    if get_space_state() == -127 or get_space_state() == -128:
        print ("yes")
        pyautogui.click(clicks=40 , interval=0.01) 

Большое спасибо.


person User New    schedule 22.05.2016    source источник


Ответы (1)


Правильный ответ: я подозреваю постоянный опрос из-за while True:. Вставьте sleep или pyautogui.PAUSE там (внутри цикла while, перед if), если процесс некоторое время спит (даже меньше секунды) освобождает много циклов процессора

Незначительные оптимизации: также вы инициализируете всю User32.dll в каждом цикле... кажется, дважды (из-за or). А User32 ОГРОМНЫЙ

Советы и примечания:

Если я правильно помню правила Python, вы просто можете переместить hllDll на уровень модуля (выше определения функции), get_space_state() все равно его найдет. Или вы можете передать его как параметр. И вам не нужно переопределять VK_SPACE каждый вызов функции - хотя это микро-оптимизация

Если все эти исправления не работают, вам следует использовать отладчики, чтобы найти истинный источник замедлений.

Если у вас возникнут подобные проблемы в будущем, используйте что-то вроде Immunity или WinDbg, чтобы подключиться к процессу и посмотреть, что там происходит

person strangeqargo    schedule 22.05.2016
comment
Спасибо за Ваш ответ. 1) Как и куда вставлять сон? 2) примерно дважды - я менял на if get_space_state() ‹ 0: - ничего не улучшилось. 3) Знаете ли вы, как инициализировать НЕ всю User32.dll, а только нужную ее часть? - person User New; 22.05.2016
comment
к сожалению, нет, я не знаю, как экспортировать одну функцию, но это не будет иметь большого значения, если вы просто экспортируете lib один раз - при загрузке - person strangeqargo; 22.05.2016
comment
Ты прав. Проблема решается всего одной строкой: time.sleep(0.02), вставляемой перед if. Все остальное вообще не имеет значения. - person User New; 22.05.2016
comment
Это может иметь значение, но только при очень высокой нагрузке, я думаю, что не вариант для простого кликера :) - person strangeqargo; 22.05.2016