Как я могу ускорить поколения массива в Python?

Я думаю, что должен использовать numpy или некоторую другую библиотеку для заполнения этих массивов достаточно быстро, но я не знаю много об этом. Прямо сейчас эта операция занимает приблизительно 1 секунду на четырехъядерном Intel PC, но мне нужна она, чтобы быть максимально быстро. Любая справка значительно ценится.Спасибо!

import cv

class TestClass:

  def __init__(self):

    w = 960
    h = 540

    self.offx = cv.CreateMat(h, w, cv.CV_32FC1)
    self.offy = cv.CreateMat(h, w, cv.CV_32FC1)

    for y in range(h):
      for x in range(w):
        self.offx[y,x] = x
        self.offy[y,x] = y
6
задан bparker 4 July 2010 в 22:51
поделиться

5 ответов

Вы генерируете полмиллиона целых чисел и создаете более миллиона ссылки, пока вы на нем. Я был бы счастлив, что это займет всего 1 секунду.

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

Кроме того, четырехъядерный процессор ничего не помогает в таком случае, вы выполняете последовательную операцию, которая может выполняться только на одном ядре за раз (и даже если вы ее распределили, CPython может только выполнять по одному потоку чистого Python за раз из-за глобальной блокировки интерпретатора).

1
ответ дан 10 December 2019 в 00:32
поделиться

Код в Numpy, который делает то же самое, что и OpenCV в python -

import numpy as np
offsetx, offsety = np.meshgrid(range(960),range(540))

Если вы используете Python, то изучение различных функций numpy очень поможет вам. Функции OpenCV также могут работать непосредственно с массивами numpy. Однако синтаксис numpy в Python намного лучше, чем в OpenCV.

Вот время работы двух версий на моем i7

time python test.py

real    0m0.654s 
user    0m0.640s
sys 0m0.010s

Моя версия:

time python test2.py

real    0m0.075s
user    0m0.060s
sys 0m0.020s
1
ответ дан 10 December 2019 в 00:32
поделиться

Мой восьмилетний (медленный) компьютер способен создать список списков того же размера, что и ваша матрица, за 127 миллисекунд.

C:\Documents and Settings\gdk\Desktop>python -m timeit "[[x for x in range(960)]
 for y in range(540)]"
10 loops, best of 3: 127 msec per loop

Я не знаю, что такое модуль cv и как он создает матрицы. Но, возможно, это и есть причина медленного кода.

Numpy может быть быстрее. Создание массива (python int) 1s:

C:\Documents and Settings\gdk\Desktop>python -m timeit -s "from numpy import one
s" "ones((960, 540), int)"
100 loops, best of 3: 6.54 msec per loop

Вы можете сравнить время создания матриц с помощью разных модулей, чтобы понять, есть ли польза от замены: модуль timeit

8
ответ дан 10 December 2019 в 00:32
поделиться

Ну, вы можете по крайней мере использовать xrange вместо диапазона. range создает полный список всех этих чисел. xrange генерирует их 1 к 1. Поскольку вы используете их только по одному, вам не нужен их список.

0
ответ дан 10 December 2019 в 00:32
поделиться

Если вы создаете одну и ту же матрицу снова и снова, возможно, будет быстрее инициализировать ее с помощью cv.SetData()

0
ответ дан 10 December 2019 в 00:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: