Найти - Пользователи
Полная версия: Профилирование
Начало » Python для новичков » Профилирование
1
Обедающий философ
Здравствуйте!

Написал программу, а она зело медленно работает. Посему решил ознакомиться с таким чудом человеческой мысли, как профилировка. Сначала сделал как здесь http://docs.python.org/library/profile.html - то бишь написал cProfile.run('simulate(1000, 10)') , а питон мне в ответ NameError: name ‘simulate’ is not defined, хотя без профилирования это же выражение замечательно работает. Затем ещё немного поискал и нашёл сие http://habrahabr.ru/blogs/python/110537/ , сделал как предлагается через hotshot, но в результате получается файл всего ничего в 423 байта, среди которых интересующей меня информации ровно ноль.

Что я делаю не так?

Заранее благодарен.
Александр Кошелев
profile = cProfile()
profile.runcall(simulate, 1000, 10)

profile.dump_stats('profiler.data')
Андрей Светлов
Я почему-то предпочитал вместо runcall использовать runctx('simulate(1000, 10)', globals(), locals())
http://docs.python.org/library/profile.html?highlight=runctx#cProfile.runctx
Обедающий философ
Премного благодарен! Через runctx получилось. Однако вопросов это не решило, а поставило ещё ряд вопросов. Не знаю, как принято на настоящем форуме насчёт разделения тем, посему задам их пока что здесь. Вопросы, наверное, глупые.

В общем, у меня система - трёхмерный массив, а в каждой клетке может быть или не быть частица, причём эти частицы ещё могут двигаться (на одну клетку за раз). Пока что движутся случайно, потом будут двигаться по показаниям нейронной сети. И чтобы они при движении не попадали по несколько в одну и ту же клетку, я строю систему на следующем шаге и последовательно отменяю движение у неправильно движущихся частиц.

А вопросы следующего характера. В процессе вышеуказанного действа в основном мне надо выполнять операции трёх видов - копирование массива, поэлементное применение функции к одному массиву с записью результатов в другой массив и проход по ячейкам массива, но не просто так, а чтобы можно было узнавать и изменять значения соседних клеток, а также клеток с этими же координатами в других массивах. Массивы у меня из numpy.

Так вот, для первых двух задач я написал такую функцию:

def assign3d(dst, fun, src):
xr=range(src.__len__())
yr=range(src[0].__len__())
zr=range(src[0, 0].__len__())
for i in xr:
for j in yr:
for k in zr:
dst[i, j, k]=fun(src[i, j, k])
То бишь она последовательно применяет функцию к элементам одного массива и записывает результат в другой. И профилирование показала, что сия функция почти половину времени отнимает (скажем, копирование массива функцией lambda a: a идёт со скоростью миллион ячеек в секунду, процессор core i3-530). И проход по координатам (третья задача) у меня тоже приблизительно в том же ключе.

Посему вопрос - как грамотно производить означенные операции? И стоит ли овчинка выделки, то бишь намного ли увеличится скорость? Я, конечно, знаю, что преждевременной оптимизацией выложена дорога в ад, но в данном случае на мой взгляд это как-то чересчур.

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

Заранее благодарен.
bazooka
а можно пример этого самого массива src
Обедающий философ
Ну вот как-то так они объявляются.

def map2d(f, a):
return map(lambda b: map(f, b), a)

def map3d(f, a):
return map(lambda b: map2d(f, b), a)

def bernoulli(mean):
return 0 if random.random()>mean else 1

def randarray3d(x0, y0, z0, mean):
x, y, z = ogrid[0:x0:1, 0:y0:1, 0:z0:1]
return asarray(map3d(lambda a: bernoulli(mean), zeros((world_x,world_y,world_z), int)))

agents3d = randarray3d(world_x,world_y,world_z, initial_agents)
agents3d_future = zeros((world_x,world_y,world_z), int)
motion3d_raw = zeros((world_x,world_y,world_z, 3), float)
motion3d_refined = zeros((world_x,world_y,world_z), int)
Здесь мы видим ещё один способ применения функции к массиву, однако, во-первых, я не уверен, что так будет быстрее, а во-вторых я не знаю, как присваивать целый массив из функции (они у меня пока что как глобальные переменные, наверное ежели сделать объект и обращаться через self, то будет лучше).
Александр Кошелев
Обедающий философ
Не знаю, как принято на настоящем форуме насчёт разделения тем, посему задам их пока что здесь. Вопросы, наверное, глупые.
Единственно разумно – одна тема один вопрос.
Обедающий философ
Пролистал документацию numpy от начала и до конца. Нашёл copy и piecewise. А вот как банально применить функцию ко всему массиву (то бишь не генерируя при этом массив истин) - не нашёл.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB