Уведомления

Группа в Telegram: @pythonsu

#1 Май 6, 2011 23:35:58

Обедающий философ
От:
Зарегистрирован: 2011-05-06
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Профилирование

Здравствуйте!

Написал программу, а она зело медленно работает. Посему решил ознакомиться с таким чудом человеческой мысли, как профилировка. Сначала сделал как здесь 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 байта, среди которых интересующей меня информации ровно ноль.

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

Заранее благодарен.



Офлайн

#2 Май 7, 2011 00:20:15

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Профилирование

profile = cProfile()
profile.runcall(simulate, 1000, 10)

profile.dump_stats('profiler.data')



Офлайн

#3 Май 7, 2011 05:40:51

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Профилирование

Я почему-то предпочитал вместо runcall использовать runctx('simulate(1000, 10)', globals(), locals())
http://docs.python.org/library/profile.html?highlight=runctx#cProfile.runctx



Офлайн

#4 Май 7, 2011 19:26:15

Обедающий философ
От:
Зарегистрирован: 2011-05-06
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Профилирование

Премного благодарен! Через 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). И проход по координатам (третья задача) у меня тоже приблизительно в том же ключе.

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

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

Заранее благодарен.



Офлайн

#5 Май 8, 2011 11:12:27

bazooka
От:
Зарегистрирован: 2009-04-12
Сообщения: 165
Репутация: +  0  -
Профиль   Отправить e-mail  

Профилирование

а можно пример этого самого массива src



Офлайн

#6 Май 8, 2011 12:21:49

Обедающий философ
От:
Зарегистрирован: 2011-05-06
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Профилирование

Ну вот как-то так они объявляются.

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, то будет лучше).



Офлайн

#7 Май 8, 2011 20:38:58

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Профилирование

Обедающий философ
Не знаю, как принято на настоящем форуме насчёт разделения тем, посему задам их пока что здесь. Вопросы, наверное, глупые.
Единственно разумно – одна тема один вопрос.



Офлайн

#8 Май 16, 2011 20:11:02

Обедающий философ
От:
Зарегистрирован: 2011-05-06
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Профилирование

Пролистал документацию numpy от начала и до конца. Нашёл copy и piecewise. А вот как банально применить функцию ко всему массиву (то бишь не генерируя при этом массив истин) - не нашёл.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version