-1

I am developing a small Python program that simulates pressing, holding, and releasing keys with random delays. This is intended to make the process look more natural, as if a real person is typing rather than a machine.

However, I encountered a significant problem: the total execution time of the program is 293.97 ms, which is approximately three times longer than the sum of the delays for key press (49 ms) and key release (42 ms), totaling 91 ms.

import time
import random
import pyautogui


def key_sim(key, min_delay_ms, max_delay_ms):
    # Start time before keyDown
    start_time = time.perf_counter()

    pyautogui.keyDown(key)
    delay_ms = random_delay(min_delay_ms, max_delay_ms)
    time.sleep(delay_ms)

    pyautogui.keyUp(key)
    delay_ms = random_delay(min_delay_ms, max_delay_ms)
    time.sleep(delay_ms)

    # End time after keyUp
    end_time = time.perf_counter()

    return end_time - start_time


def random_delay(min_delay_ms, max_delay_ms):
    delay_ms = random.randint(min_delay_ms, max_delay_ms)
    delay_s = delay_ms / 1000.0  # Convert milliseconds to seconds
    print(f"Delay: {delay_ms} ms")
    return delay_s


# Execution
last_time = time.perf_counter()
execution_time = key_sim('a', 30, 60)
print("Total execution time: {:.2f} ms".format(execution_time*1000))

resultant of code:

..\main.py 
 Delay: 49 ms
 Delay: 42 ms
 Total execution time: 293.97 ms

Process finished with exit code 0

how to optimize code to minimize difference between sum of two delay and Total execution time?

Thank you in advance for your reply!

2
  • 2
    Reduce the sleep time? Commented Jun 4 at 8:27
  • if you reduce pyautogui.keyUp(key) and pyautogui.keyDown(key) the timings more or less match up; also note that perf_counter counts system time too, point is, pyautogui is adding to your time, just decrease the delays like mentioned above Commented Jun 4 at 9:30

2 Answers 2

1

pyautogui has a delay after each action. You can add pyautogui.PAUSE = 0 to your program to remove this pause. Changing just the last block:

# Execution
pyautogui.PAUSE = 0
last_time = time.perf_counter()
execution_time = key_sim('a', 30, 60)
print("Total execution time: {:.2f} ms".format(execution_time*1000))

Resulting in:

Delay: 45 ms
Delay: 36 ms
Total execution time: 83.51 ms
Sign up to request clarification or add additional context in comments.

Comments

1

Instead of manually using time.perf_counter() to measure execution times in the code, just use the Python profiler.

Simplest use case:

python3.11 -m cProfile -s tottime main.py

Will show you the time spent in every function sorted by time spent in its code. Use -s cumtime to sort by time spent in the function and all other functions called by it.

Much better is to import cProfile into the code and profile the sections you need.

That said, in this case the delays are in pyautogui.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.