Долгосрочная функция Python-скрипта - PullRequest
1 голос
/ 10 марта 2019

Здравствуйте, у меня проблема в том, что выполнение функции в моем скрипте занимает много времени.Поэтому я пытаюсь оптимизировать код, и в настоящее время я использую для этого cProfile и Pstats.

Когда я выполняю функцию, она занимает от 0,7 до 1+ секунд.Элемент, который всегда дает наибольшую продолжительность в Windows:

    Sun Mar 10 13:55:02 2019    profiles/getColors.profile

         657 function calls in 0.535 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
          1    0.714    0.714    0.714    0.714 {built-in method _winapi.WaitForMultipleObjects}_winapi.WaitForMultipleObjects}

И в Linux:

2    1.013    0.506    1.013    0.506 {built-in method posix.read}

Так что я собираюсь предположить, что это связано с многопоточностью, но я никогдасоздайте любые потоки, и моя другая функция почти не тратит время на завершение, как ~ 0,1 сек, поэтому мой вопрос: почему так долго выполняется этот код:

def getColors(image, rows, columns, sectionedPixel):
# Flooring so we do not get decimal numbers
sectionColumns = math.floor(width / columns)
sectionRows = math.floor(height / rows)
colorValues = [0, 0, 0, 0]
leftRGBVal = [0, 0, 0]
rightRGBVal = [0, 0, 0]
topRGBVal = [0, 0, 0]
botRGBVal = [0, 0, 0]

# LEFT SIDE
getRiLeSideColor(image, 0, 10, leftRGBVal)
# RIGHT SIDE
getRiLeSideColor(image, width - 10, width, rightRGBVal)

# TOP SIDE
getToBoSideColor(image, 0, 10, topRGBVal)
# BOTTOM SIDE
getToBoSideColor(image, height - 10, height, botRGBVal)

colorValues[0] = leftRGBVal
colorValues[1] = rightRGBVal
colorValues[2] = topRGBVal
colorValues[3] = botRGBVal

return colorValues

Полный журнал CProfile: https://pastebin.com/jAA5FkPZ

Полный код: https://gist.github.com/Patrick265/592a7dccba4660a4e4210ddd5e9974eb

1 Ответ

1 голос
/ 10 марта 2019

Если я просто запускаю ваш скрипт и проверяю время двух основных вызовов retrieveScreen(...) и getColors(...), я вижу среднее время:

retrieveScreen: 1.70369
getColors:      0.07770

Полагаю, ваш экран использует операционную систему и просто требует времени.

Из нескольких быстрых тестов я думаю, что должно быть быстрее получить PixelAccess вашего экрана примерно так, просто используя голое PIL:

import PIL.ImageGrab

pxlaccess = PIL.ImageGrab.grab().load()

Редактировать: полный пример

Этот код (python3) использует только PIL. Честно говоря, я не уверен в том, какой метод подушек используется для доступа к экрану, но он немного быстрее, чем ваш предыдущий подход. Я думаю, что вы пытаетесь добиться чего-то вроде подсветки экрана, которая требует обновления довольно быстро; не знаю, достаточно ли это для вашей цели или нет. Тем не менее, не стесняйтесь использовать код по мере необходимости:

#!/usr/bin/python3

import time
import PIL.ImageGrab


def get_screen_and_dimensions():
    cap = PIL.ImageGrab.grab()
    return cap.load(), cap.size


def average_color_from_rect(screen, x0, x1, y0, y1):
    color = [0, 0, 0]
    for x in range(x0, x1):
        for y in range(y0, y1):
            source = screen[x, y]
            for i in range(3):
                color[i] += source[i]
    count = (x1 - x0) * (y1 - y0)
    return [round(color[i] / count) for i in range(3)]


def main():
    t0 = time.time()
    screen, size = get_screen_and_dimensions()
    t1 = time.time()
    print(f'Grab screen: {t1 - t0:.4f}s')

    bandwidth = 10
    borders = {
        'top': (0, size[0], 0, bandwidth),
        'right': (size[0] - bandwidth, size[0], 0, size[1]),
        'bottom': (0, size[0], size[1] - bandwidth, size[1]),
        'left': (0, bandwidth, 0, size[1]),
    }

    t0 = time.time()
    for border, args in borders.items():
        color = average_color_from_rect(screen, *args)
        print(f'{border}: {color}')
    t1 = time.time()
    print(f'Color calculation: {t1 - t0:.4f}s')


if __name__ == "__main__":
    main()

Примерный вывод, только для демонстрационных целей:

$ python3 fiddle-colors.py 
Grab screen: 0.3974s
top: [35, 35, 35]
right: [126, 126, 125]
bottom: [134, 137, 139]
left: [50, 50, 50]
Color calculation: 0.0905s
...